Ось свойство позиции относительно его родительского контейнера.Следовательно, одна из возможностей - создать прозрачную панель того же размера, что и первая ось, затем внутри нее создать вторую ось и при необходимости установить ее местоположение и размер.Указанная позиция будет выглядеть так, как если бы она была относительно первой оси.
Теперь нам нужно всегда поддерживать размер панели / тот же размер / расположение, что и у первой оси.Обычно это можно сделать с помощью LINKPROP , который связывает свойство нескольких графических объектов (панель и ось) как одно и то же, а именно свойство 'Position'
.
Однако это может произойти сбой вВаш случай: при вызове axis image
он фиксирует одинаковые единицы измерения в каждом направлении, устанавливая свойства формата изображения, такие как 'PlotBoxAspectRatio'
и 'DataAspectRatio'
.Печальная новость заключается в том, что свойство 'Position'
не будет отражать изменение размера, что нарушит вышеуказанное решение.Вот пример, иллюстрирующий проблему: если вы запросите свойство position до / после вызова axis image
, оно будет таким же:
figure, plot(1:10,1:10)
get(gca,'Position')
pause(1)
axis image
get(gca,'Position')
К счастью для нас, на 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')
И реализация функции:
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
![axesRelative](https://i.stack.imgur.com/2i4c8.png)
На совершенно другом замечании: перед вашим недавним редактированием у меня сложилось впечатление, что вы пытались создать точечный график изображений (то есть, как обычный точечный график, но с полными изображениями вместоточек).
То, что вы предложили (насколько я понимаю), создает одну ось для каждого изображения и устанавливает ее положение, соответствующее координатам 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')
![image_scatter](https://i.stack.imgur.com/qwv9Y.png)