An axis 位置属性 http://www.mathworks.com/help/matlab/ref/axes_props.html#Position是相对于其父容器的。因此,一种可能性是创建一个透明的panel http://www.mathworks.com/help/matlab/ref/uipanel.html与第一个轴的大小相同,然后在其中创建第二个轴,并根据需要设置其位置和大小。指定的位置就好像它是相对于第一个轴的。
现在我们需要始终保持面板与第一个轴的大小/位置相同。通常这可以使用LINKPROP http://www.mathworks.com/help/matlab/ref/linkprop.html它将多个图形对象(面板和轴)的一个属性链接为相同的,即'Position'
财产。
但是,这在您的情况下会失败:调用时axis image http://www.mathworks.com/help/matlab/ref/axis.html#f17-644352,它通过设置宽高比属性将数据单元固定在每个方向上相同'PlotBoxAspectRatio'
and 'DataAspectRatio'
。令人悲伤的消息是'Position'
属性不会反映大小的变化,从而打破了上面的解决方案。下面是一个说明问题的例子:如果您在发出之前/之后查询位置属性axis image
调用,结果是一样的:
figure, plot(1:10,1:10)
get(gca,'Position')
pause(1)
axis image
get(gca,'Position')
对我们来说幸运的是,FEX 上有一个提交(绘图盒位置 http://www.mathworks.com/matlabcentral/fileexchange/9615-plotboxpos)解决了这个确切的问题,并返回轴绘图区域的实际位置。一旦我们有了这个,就需要将面板位置同步到轴位置。一个技巧是在轴改变大小时创建一个事件侦听器(它出现 http://www.mathworks.com/matlabcentral/answers/5882-getting-the-axis-position-correctly认为'TightInset'
属性变化与'Position'
属性,因此这可能是我们案例中的触发器)。
我将上面的内容封装在一个函数中AXESRELATIVE
为了方便起见:您可以像调用内置函数一样调用它AXES http://www.mathworks.com/help/matlab/ref/axes.html功能。唯一的区别是您将要相对定位新创建的轴的轴的句柄作为第一个参数。它返回新轴及其包含面板的句柄。
这是一个示例用法:
%# automatic resize only works for normalized units
figure
hParentAx = axes('Units','normalized');
axis(hParentAx, 'image')
%# create a new axis positioned at normalized units with w.r.t the previous axis
%# the axis should maintain its relative position on resizing the figure
[hAx hPan] = axesRelative(hParentAx, ...
'Units','normalized', 'Position',[0.7 0.1 0.1 0.1]);
set(hAx, 'Color','r')
以及函数实现:
function [hAx hPan] = axesRelative(hParentAx, varargin)
%# create panel exactly on top of parent axis
s = warning('off', 'MATLAB:hg:ColorSpec_None');
hPan = uipanel('Parent',get(hParentAx, 'Parent'), ...
'BorderType','none', 'BackgroundColor','none', ...
'Units',get(hParentAx,'Units'), 'Position',plotboxpos(hParentAx));
warning(s)
%# sync panel to always match parent axis position
addlistener(handle(hParentAx), ...
{'TightInset' 'Position' 'PlotBoxAspectRatio' 'DataAspectRatio'}, ...
'PostSet',@(src,ev) set(hPan, 'Position',plotboxpos(hParentAx)) );
%# create new axis under the newly created panel
hAx = axes('Parent',hPan, varargin{:});
end
完全不同的说明:在您最近进行编辑之前,我的印象是您试图生成图像散点图(即像通常的散点图一样,但使用完整图像而不是点)。
您的建议(据我了解)是为每个图像创建一个轴,并将其位置设置为与该点的 x/y 坐标相对应。
我的解决方案是使用IMAGE http://www.mathworks.com/help/matlab/ref/image.html/IMAGESC http://www.mathworks.com/help/matlab/ref/imagesc.html函数并通过显式设置来绘制小图像'XData'
and 'YData'
属性来适当地移动和缩放图像。这样做的好处是它需要一个轴,并且不必处理调整大小的问题。
这是一个示例实现:
%# create fan-shaped coordinates
[R,PHI] = meshgrid(linspace(1,2,5), linspace(0,pi/2,10));
X = R.*cos(PHI); Y = R.*sin(PHI);
X = X(:); Y = Y(:);
num = numel(X);
%# images at each point (they don't have to be the same)
img = imread('coins.png');
img = repmat({img}, [num 1]);
%# plot scatter of images
SCALE = 0.2; %# image size along the biggest dimension
figure
for i=1:num
%# compute XData/YData vectors of each image
[h w] = size(img{i});
if h>w
scaleY = SCALE;
scaleX = SCALE * w/h;
else
scaleX = SCALE;
scaleY = SCALE * h/w;
end
xx = linspace(-scaleX/2, scaleX/2, h) + X(i);
yy = linspace(-scaleY/2, scaleY/2, w) + Y(i);
%# note: we are using the low-level syntax of the function
image('XData',xx, 'YData',yy, 'CData',img{i}, 'CDataMapping','scaled')
end
axis image, axis ij
colormap gray, colorbar
set(gca, 'CLimMode','auto')