如何相对于另一个轴定位图中的轴?

eyk*_*nal 8 matlab image figure

在MATLAB中布置图形时,键入axis equal可确保无论图形尺寸如何,始终为方形:

在此输入图像描述

我目前的问题是我想在这个情节中添加第二个轴.通常,这没问题; 我只想输入axes([x1 y1 x2 y2]),然后添加一个新的方形图形(x1, y1), (x2, y2),其中有一个角,相对于图形是一个固定的位置.问题是,我希望这个新轴位于相对于第一轴的固定位置.

所以,我的问题是:

  1. 有没有人知道如何通过指定相对于另一个轴的位置来定位图中的轴?
  2. 假设我可以做1,即使调整大小,我怎么能让这些新轴保持在同一个位置?

Amr*_*mro 13

位置属性相对于其父容器.因此,一种可能性是创建与第一轴具有相同尺寸的透明面板,然后在其内部创建第二轴,并根据需要设置其位置和尺寸.指定的位置就好像它相对于第一个轴.

现在我们需要始终将面板保持为与第一轴相同的尺寸/位置.通常这可以使用LINKPROP来完成,LINKPROP将多个图形对象(面板和轴)的属性链接为相同,即'Position'属性.

但是,在您的情况下,这将失败:在调用时axis image,它通过设置像'PlotBoxAspectRatio'和这样的宽高比属性,将数据单元固定在每个方向上相同'DataAspectRatio'.令人遗憾的是,该'Position'物业不会反映出规模的变化,从而打破了上述解决方案.下面是一个说明问题的示例:如果在发出axis image调用之前/之后查询position属性,它将是相同的:

figure, plot(1:10,1:10)
get(gca,'Position')
pause(1)
axis image
get(gca,'Position')
Run Code Online (Sandbox Code Playgroud)

对我们来说幸运的是,有一个关于FEX(plotboxpos)的提交解决了这个问题,并返回了轴的绘图区域的实际位置.一旦我们有了这个,就需要将面板位置同步到轴位置.一个窍门是创建当轴改变大小事件监听器(它出现'TightInset'不同的属性更改'Position'属性,因此这可能是在我们的情况下触发).

AXESRELATIVE为方便起见,我将上面的内容包装在一个函数中:您可以像调用内置的AXES函数一样调用它.唯一的区别是你把它作为第一个参数给你想要相对定位新创建的轴的轴的句柄.它将句柄返回到新轴及其包含的面板.

以下是一个示例用法:

%# 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')
Run Code Online (Sandbox Code Playgroud)

而功能实现:

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
Run Code Online (Sandbox Code Playgroud)

axesRelative


在一个完全不同的注释:在你最近的编辑之前,我得到的印象是你试图产生一个图像的散点图(即像通常的散点图,但用完整的图像而不是点).

你所建议的(根据我的理解)是为每个图像创建一个轴,并设置其位置对应于点的x/y坐标.

我的解决方案是使用IMAGE/IMAGESC函数并通过显式设置'XData''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')
Run Code Online (Sandbox Code Playgroud)

image_scatter