Bubbleplot function from file exchange: overlapping text and positioning

조회 수: 1 (최근 30일)
yvesvincent abgrall
yvesvincent abgrall 2019년 11월 8일
댓글: darova 2019년 11월 8일
Hello all,
I'm having a hard time figuring out how to place well the data point text on the scatter plot ploted using this function:
I want the text to be at the limit of the marker (circles by default) but I don't figure out a way of doing so. I tried setting the axis units to a different type but nothing.
function [lh, th] = bubbleplot(x, y, z, siz, col, shape, varargin)
error(nargchk(2,10,nargin,'struct'));
% Default z
if nargin < 3
z = [];
end
% Default size
if nargin < 4 || isempty(siz)
siz = 8;
end
if nargin < 5 || isempty(col)
col = z;
end
if nargin < 6 || isempty(shape)
shape = 'o';
end
p = inputParser;
p.addOptional('Text',{},@(x)iscellstr(x)||(ischar(x)&&size(x,1)>1)||(~ischar(x)&&length(x)>1));
p.addParamValue('ShowText',true);
p.addParamValue('FontSize',8);
p.addParamValue('Alignment', 'left');
p.addParamValue('MarkerSizeLimits',[3 20]);
p.addParamValue('ColorMap',@cool);
p.parse(varargin{:});
desctext = p.Results.Text;
showText = p.Results.ShowText;
if isempty(desctext), showText = false; end
fontSize = p.Results.FontSize;
alignment = p.Results.Alignment;
colmapfun = p.Results.ColorMap;
markerSizeLimits = p.Results.MarkerSizeLimits;
%% Determine marker colors
if ischar(colmapfun)
colmapfun = str2func(colmapfun);
elseif isnumeric(colmapfun)
colmapfun = @(x)colmapfun(1:min(x,end),:);
end
if isempty(col)
col = zeros(size(x));
end
[uniqueCols, gar, colInd] = unique(col);
if isinteger(col) || isa(col,'categorical') || iscell(col) || length(uniqueCols)<=.1*length(col) || all(round(col)==col) % Is col categorical
% Generate a colormap with one level per unique entry in col
colmap = colmapfun(length(uniqueCols));
else
% Scale the color values to span the colormap
colmap = colmapfun(256);
mx = max(col);
n = min(col);
if mx == n, mx = n + 1; end
colInd = (col-n)/(mx-n)*(size(colmap,1)-1)+1;
end
try
color = colmap(round(colInd),:);
catch %#ok<CTCH>
error('The custom colormap must have at least %d levels', max(colInd));
end
%% Determine marker shape
if ischar(shape)
markertype = repmat(shape(1),size(x));
else
markerseq = 'osd^><vph.*+x';
[uniqueShapes, gar, shapeInd] = unique(shape);
if length(uniqueShapes)>length(markerseq)
error('BubblePlot can only support 13 unique shapes');
end
markertype = markerseq(shapeInd);
end
%% Determine marker size
if isscalar(siz)
siz = repmat(siz, size(x));
markersize = siz;
else % Map the siz variable to a markersize between a minimum and maximum
minsize = markerSizeLimits(1);
maxsize = markerSizeLimits(2);
markersize = (siz - min(siz))/(max(siz)-min(siz))*(maxsize - minsize)+minsize;
end
%% Clean up data - handle NaNs
markersize(isnan(markersize)) = .01; % These will not be drawn as regular markers, just pixel points
%isnan(x) | isnan(y) | isnan(z) | isnan(col) |
%% Plot data
% Create structure to store original data in every graphics object (for
% subsequent retrieval, eg: with data tip)
pointData = struct('x',num2cell(x),'y',num2cell(y),'siz',num2cell(siz),'col',num2cell(col),...
'shape',num2cell(shape));
if nargin > 6 && ~isempty(desctext)
if ~iscellstr(desctext)
desctext = cellstr(desctext);
end
[pointData.text] = desctext{:};
end
if isempty(z)
plotfun = @plot;
%plotfun = @patch;
%zarg = {color(1,:)};
zarg = {};
else
plotfun = @plot3;
zarg = {z(1)};
zdata = num2cell(z);
[pointData.z] = zdata{:};
end
lh = zeros(1,length(x)); % Line Handles
lh(1) = customPlot(plotfun, pointData(1), color(1,:), markersize(1), markertype(1), x(1), y(1), zarg{:});
for i = 2:length(lh)
if isempty(z), zarg = {}; else zarg = {z(i)}; end
%if isempty(z), zarg = {color(i,:)}; else zarg = {z(i)}; end
lh(i) = customPlot(@line, pointData(i), color(i,:), markersize(i), markertype(i), x(i), y(i), zarg{:});
%lh(i) = customPlot(@patch, pointData(i), color(i,:), markersize(i), markertype(i), x(i), y(i), zarg{:});
end
if showText
hAxes = get(lh(1),'Parent');
offset = diff(get(hAxes,'Ylim'))*.01;
if isempty(z)
z = zeros(size(x));
end
th = text(x, y-offset, z, desctext, 'Fontsize', fontSize, 'HorizontalAlignment', alignment);
lims = get(hAxes,{'XLim','YLim','ZLim'});
lims = vertcat(lims{:});
factor = fontSize.*diff(lims,[],2);
addlistener(hAxes,{'XLim','YLim'},'PostSet',@(obj,evdata)resizeText(hAxes, th, y, factor));
%addlistener(get(hAxes,'Parent'),'Resize',@(obj,evdata)resizeText(hAxes, th));
else
th = [];
end
function lh = customPlot(funh, pointData, c, siz, markertype, varargin)
lh = funh(varargin{:});
set(lh, 'Marker', markertype,...
'LineStyle', 'none', 'Color', c, ...
'MarkerFaceColor', c, ...
'MarkerEdgeColor', [0 0 0], 'MarkerSize', siz,...
'UserData', struct('Point',pointData));
% lh = patch('XData',x(i),'YData', y(i), 'ZData', z(i), 'Marker', 'o',...
% 'LineStyle', 'none', 'CData', color, 'MarkerFaceColor', c, ...
% 'MarkerEdgeColor', [0 0 0], 'MarkerSize', siz2(i), 'FaceAlpha', .4, 'EdgeAlpha', .2, ...
% 'UserData', data);
function resizeText(hAxes, hText, y, factor) %#ok<*INUSD>
lims = get(hAxes,{'XLim','YLim','ZLim'});
lims = vertcat(lims{:});
% Uncomment following to update fontsize
% newfs = min([factor(1:2)./diff(lims(1:2,:),[],2) ; 24]);
% set(hText,'FontSize',newfs);
% Update position
offset = diff(get(hAxes,'Ylim'))*.01;
p = get(hText,'Position');
p = vertcat(p{:});
outofbounds = any(bsxfun(@gt,p,lims(:,2)') | bsxfun(@lt,p,lims(:,1)'), 2);
set(hText(outofbounds),'Visible','off');
set(hText(~outofbounds),'Visible','on');
% Adjust offsets
p(:,2) = y - offset;
for i = 1:length(p)
set(hText(i),'Position',p(i,:));
end
I have some points with the same coordinates and the text associated with these points are overlapping.
I added a function to re-set the text position using the text handle :
function fitText(hText,mrkrSize)
for i=1:length(hText)
disp(hText(1).Position)
disp(mrkrSize(1))
[newposx, newposy, newposz]=pos(hText(i).Position, mrkrSize(i));
set(hText(i),'Position',[newposx, newposy, newposz]);
end
function [a,b,c] = pos(posX0,mrkrsize)
a = posX0(1)+mrkrsize/10;
b = posX0(2)+mrkrsize/10;
c = posX0(3);
Do you have any clue of doing it properly?
thanking you in advance
  댓글 수: 1
darova
darova 2019년 11월 8일
Can you show your original image and the picture your want to achieve? Maybe simple drawing?

댓글을 달려면 로그인하십시오.

답변 (0개)

카테고리

Help CenterFile Exchange에서 Graphics Object Programming에 대해 자세히 알아보기

제품


릴리스

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by