Bubbleplot function from file exchange: overlapping text and positioning

1 次查看(过去 30 天)
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

回答(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