我有一个X Y Z数据集。 X和Y是2D坐标,Z是强度。
我使用分散函数绘制数据:
markerSize=100;
scatter(x,y,markerSize,z,'s','fill');
我使用的选项' s'和'填充'得到满满的广场。
我的问题是markerSize值对应于标记的区域,其单位是点(1/72英寸)。
即使我调整了图形的大小,标记大小也是不变的。因此,当我增加数字大小时,数据点之间的差距会增大。
我想要的是恒定的标记尺寸,它是轴单位的常数。例如,标记大小应为5x5(X轴为5,Y轴为5)。
感谢您的帮助。
答案 0 :(得分:4)
您希望使标记的大小与图形大小成比例。
标记的大小由SizeData
对象的scattergroup
参数控制。图的大小存储在Position
对象的figure
参数中。困难的部分是在图形大小改变时以交互方式调整标记的大小。因此,您需要使用ResizeFcn
回调并调用您定义的setmarkersize
函数。
function [ ] = setmarkersize( src, evnt )
% # get position of the figure (pos = [x, y, width, height])
pos = get(src, 'Position');
% # get the scattergroup object
h = get(get(src,'children'),'children');
% # resize the marker
relativesize = 0.5;
set(h,'SizeData', pos(3)*relativesize);
end
================================================
% # attach the callback to figure
f = figure('ResizeFcn', @setmarkersize);
h = scatter(x,y,markerSize,z,'s','fill');
答案 1 :(得分:2)
您必须根据屏幕上的实际图形大小手动设置标记大小。使用axes属性Position
,您可以将数据单位转换为相对数字单位。在下一步中,可以将此大小转换为屏幕上的点的绝对大小。有了这些信息,您可以相应地设置标记大小。在下面的代码片段中,我将轴的x / y轴限制和宽度/高度设置为相同的值,因为只有当标记宽度等于标记高度时,才能合理计算方形标记区域。 / p>
% test data
x = [25*rand(1,10) 2.5];
y = [25*rand(1,10) 2.5];
z = [rand(1,10) 0.5];
% relative marker size in squared normalized figure units
marker_rel = 5;
%% Set relative marker size (approximately)
scatter(x,y,100,z,'s','fill');
% Set identical x/y limits and set axes height=widht, so that markers
% really represent squares in data units
xlim([0 25]);
ylim([0 25]);
set(gca, 'Units', 'Points');
axpos_pt = get(gca, 'Position');
axpos_pt = [axpos_pt(1) axpos_pt(2) min(axpos(3:4)) min(axpos(3:4))];
set(gca, 'Position', axpos_pt);
grid on;
grid minor;
% Set marker size relative to data units
markerSize = (marker_rel * axpos_pt(3) / diff(xlim))^2;
set(get(gca, 'children'), 'sizedata', markerSize);
事实证明,显示的标记尺寸略小于预期。显然,有一些未知(至少对我而言)大小的边界框,请参阅here。
另一种方法是绘制矩形"手动"如下面的代码片段所示(使用相同的测试数据)。调整图形大小时,矩形也会调整大小,不需要任何特殊的回调函数。
%% Use rectangles (exact)
figure;
axes;
cmp = colormap;
z_range = max(z) - min(z);
line_style = 'none'; % set to '-' to make the edges visible
for k = 1:length(x)
x_pos = x(k) - marker_rel/2;
y_pos = y(k) - marker_rel/2;
w = marker_rel;
h = marker_rel;
color = cmp( round(((z(k) - min(z))/z_range)*(length(cmp) - 1)) + 1, : );
rectangle('Position', [x_pos y_pos w h], 'FaceColor', color,...
'LineStyle', line_style);
end
grid on;
grid minor;
以上代码生成所需的标记大小:
一般来说,这些都不是正方形。如果xlim = ylim
和轴的绝对高度=轴的绝对宽度,它们可以(并且将)只是正方形。我在第一段代码片段中展示了如何实现这一目标。
答案 2 :(得分:1)
我在Matlab中心论坛上找到了一个答案,该论坛没有使用有用的dsxy2figxy函数。这是它的链接(link)
代码如下:
x = rand(1,50);
y = rand(1,50);
s = 5; %Marker width in units of X
h = scatter(x,y); % Create a scatter plot and return a handle to the 'hggroup' object
%Obtain the axes size (in axpos) in Points
currentunits = get(gca,'Units');
set(gca, 'Units', 'Points');
axpos = get(gca,'Position');
set(gca, 'Units', currentunits);
markerWidth = s/diff(xlim)*axpos(3); % Calculate Marker width in points
set(h, 'SizeData', markerWidth^2)
答案 3 :(得分:1)
ysakamoto的answer在Matlab 2014中不起作用,Mathworks将数字句柄从double更改为object。以下修改使其再次起作用:
function [ ] = setmarkersize( src, ~ )
% get position of the figure (pos = [x, y, width, height])
pos = get(src, 'Position');
% marker size
relativesize = 0.01;
% axes is not necessarily the only child of figure (e.g. colorbar may be first)
for i = 1:numel(src.Children)
if strcmpi(src.Children(i).Type, 'axes')
% make marker size depend on figure width
src.Children(i).Children.SizeData = pos(3) * relativesize;
break
end
end
end
此外,在创建图形时,它不会将标记大小设置为正确的值,直到调整大小。因此请明确调用setmarkersize
:
f = figure('ResizeFcn', @setmarkersize);
...
setmarkersize(f)
答案 4 :(得分:0)
考虑放弃'标记'并使用矩形或圆形直接在轴上绘图。 '矩形'带有曲率的命令'设置为[1 1]本质上是一个空心圆。单位是绘图单位,因此每个矩形都可以缩放:
矩形('位置',[rectCentX rectCentY widthInPlotUnits,heightInPlotUnits],'曲率',[1 1])