2013-04-04 3 views
4

У меня есть 3 объекта (фото и 2 сюжета), чтобы положить в подзаголовки на одну фигуру. Он должен выглядеть следующим образом:Как можно выровнять графики/графики в подзаголовках в MATLAB?

image

Но, как можно заметить, фото не должно быть квадратным, но прямоугольник. Я попытался сделать это таким образом (найденный здесь Matlab: How to align the axes of subplots when one of them contains a colorbar?):

main=subplot(4,4,[5,6,7,9,10,11,13,14,15]) %photo 
imagesc(im); 
axis('image') 
pion=subplot(4,4,[8,12,16]); %right plot (rotated) 
view(90, 90) 
plot(ypion,Ppion,'.k'); 
poz=subplot(4,4,1:3); %upper plot 
plot(xpoz,Ppoz,'.k'); 

pos1=get(poz,'Position') 
pos2=get(main,'Position') 
pos3=get(pion,'Position') 

pos1(3) = pos2(3); %width for the upper plot 
set(poz,'Position',pos1) 
pos3(4) = pos2(4); %height for the right plot 
set(pion,'Position',pos3) 

Все, что я получаю так: image

Как я могу заставить верхний участок, чтобы иметь ширину, как и само фото (не как фото подзаголовок)? Установка равной ширины подзаголовков не работает, так как фотография не заполняет область подзадачи.

ответ

2

Команда axis image отрегулирует отношение оси изображения. Таким образом, в принципе, если вы скорректируете соотношения между двумя графиками в одном и том же соотношении, он будет делать то, что вы хотите.

Существует одна оговорка; изображение по своей сути в 3 раза шире или выше, чем графики, из-за того, что вы построили его в подсети 3x3, против 1x3 для верхней и 3x1 для правильных участков. Таким образом, вам придется делить либо x или y отношения участков на 3.

Некоторые примеры кода:

clc, clf 

% generate some bogus data 

ypion = rand(500,1); 
Ppion = 450*rand(500,1); 

xpoz = rand(500,1); 
Ppoz = 450*rand(500,1); 

% Load photo 
photoSub = subplot(4,4,[5,6,7,9,10,11,13,14,15]); 
load mandrill 
photo = imagesc([X,X]); 
colormap(map) 

axis image 

photoAxs = gca; 
photoAxsRatio = get(photoAxs,'PlotBoxAspectRatio') 

% right plot 
subplot(4,4,[8,12,16]); 
plot(Ppion,ypion,'k.'); 
rightAxs = gca; 
axis tight 

% upper plot 
subplot(4,4,[1 2 3]); 
plot(xpoz,Ppoz,'k.'); 
topAxs = gca; 
axis tight 


% adjust ratios 
topAxsRatio = photoAxsRatio; 
topAxsRatio(2) = photoAxsRatio(2)/3.8; % NOTE: not exactly 3... 
set(topAxs,'PlotBoxAspectRatio', topAxsRatio) 

rightAxsRatio = photoAxsRatio; 
rightAxsRatio(1) = photoAxsRatio(1)/3.6; % NOTE: not exactly 3... 
set(rightAxs,'PlotBoxAspectRatio', rightAxsRatio) 

Это дает следующий результат:

Side by Side

Просто для проверки, изменение photo = imagesc([X,X]); на photo = imagesc([X;X]); дает следующее:

over-under

Обратите внимание, что я не разделил коэффициенты на 3 точно; он вышел только ОК, если я использовал факторы ближе к 4. Я не знаю, почему это так; AFAIK, фактор 3, должен сделать трюк ...

Ну что ж, по крайней мере, у вас есть что-то, чтобы работать с компанией :)

+0

Спасибо, это работает. Я некоторое время практиковал это;) Фактор «не 3» довольно загадочен. – Slav

+0

@Slav: Действительно ... возможно, это указывает на то, что мои рассуждения ошибочны, но в любом случае, пока это работает, мы можем отложить получение правильного понимания :) Когда вы когда-нибудь поймете, почему не-3 следует использовать, это здесь :) –

0

Для данного конкретного случая я предлагаю использовать низкоуровневый axes вместо высокоуровневого subplot.
Используйте свойства 'OuterPosition' трех объектов axes, которые вы создали, чтобы разместить их в нужном месте с соответствующим размером.

0

Если вы хотите изображения быть выровнены по осям (искаженное):

изменения axis('image') к axis('tight').

Если вы хотите, чтобы пропорции изображения, чтобы остаться, и для выравнивания осей к изображению:

Ну это быстрый и грязный, но после применения axis('tight'), изменить размер фигуры в соответствующем масштабе ...

+0

Действительно, что это самое простое решение, однако, оно искажает изображение; Я думаю, это не то, чего хочет OP. –

+0

Правильно, изображение не имеет надлежащего соотношения сторон. – Slav

0

Вероятно лучшее решение принято отвечать. Это решение адаптировано из оригинала, опубликованного here.

% adjust ratios 
photoAxsratio = photoAxs.PlotBoxAspectRatio(1)/photoAxs.PlotBoxAspectRatio(2); 
topAxsratio = photoAxsratio * photoAxs.Position(4)/topAxs.Position(4); 
topAxs.PlotBoxAspectRatio = [topAxsratio, 1, 1]; 

rightAxsratio = rightAxs.Position(3)/(photoAxs.Position(3)/photoAxsratio); 
rightAxs.PlotBoxAspectRatio = [rightAxsratio, 1, 1]; 

Preview:

enter image description here


Немного объяснения

Некоторые объяснения были размещены в оригинальной статье я не буду повторять их здесь.

Идея состоит в том, чтобы вычислить правильное соотношение сторон для фигур, которые необходимо изменить.

Мы имеем следующие уравнения:

Photo.width = Photo.height * Photo.ratio 
TopAxis.width = TopAxis.height * TopAxis.ratio 
RightAxis.width = RightAxis.height * RightAxis.ratio 

Пусть

TopAxis.width = Photo.width 
RightAxis.height = Photo.height 

Мы

TopAxis.height * TopAxis.ratio = Photo.height * Photo.ratio 
TopAixs.ratio = Photo.ratio * Photo.height/TopAxis.height 

RightAxis.width/RightAxis.ratio = Photo.width/Photo.ratio 
RightAxis.ratio = RightAxis.width/(Photo.width/Photo.ratio) 
Смежные вопросы