【问题标题】:How can I align plots/graphics in subplots in MATLAB?如何在 MATLAB 的子图中对齐图/图形?
【发布时间】:2013-03-26 08:18:57
【问题描述】:

我有 3 个对象(一张照片和 2 个图)要放入一个图的子图中。它应该是这样的:

但正如人们注意到的那样,照片不应该是方形的,而是矩形的。我试着这样做(在这里找到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) 

我得到的是这样的:

如何强制上部图的宽度作为照片本身(而不是照片子图)?设置子图的等宽不起作用,因为照片没有填满子图区域。

【问题讨论】:

  • 从 2020 年开始,使用tiledlayout 可能比使用subplot 更容易。

标签: matlab subplot


【解决方案1】:

命令axis image调整图像轴比。因此,原则上,如果您将两个地块的容积率调整为相同的比率,它就会为所欲为。

有一个警告;由于您已将其绘制在 3x3 子图中,而顶部为 1x3,右侧图为 3x1,因此该图像本质上比图宽或高 3 倍。因此,您必须将绘图的 xy 比率除以 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)

这给出了以下结果:

只是为了测试,将 photo = imagesc([X,X]); 更改为 photo = imagesc([X;X]); 给出以下结果:

请注意,我没有将比率除以 3完全;只有当我使用接近 4 的因子时,它才会出现。我不知道为什么会这样; AFAIK,因子 3 应该可以解决问题...

哦,好吧,至少你现在有一些工作要做:)

【讨论】:

  • 谢谢,这行得通。我花了一些时间练习它;)“不是 3”的因素很神秘。
  • @Slav:确实...也许这表明我的推理有缺陷,但无论如何,只要它有效,我们可以推迟获得正确的理解:) 当你明白为什么不 - 3应该使用,请在这里分享:)
【解决方案2】:

这是一个解决方案,可以消除已接受答案中的猜测。此解决方案改编自 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];

预览:


一点解释

部分解释已在原帖中发表,此处不再赘述。

这个想法是为需要调整大小的图形计算正确的纵横比。

我们有以下等式:

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)

【讨论】:

    【解决方案3】:

    自 matlab R2019b 发布以来,您现在可以使用:tiledlayoutnexttile

    现在很容易做到:

    % Load a random scary image
    I = im2gray(imread('https://unwinnable.com/wp-content/uploads/2011/10/The-Ring-well.jpg'));
    % Some computation...
    Sx = sum(I)/max(sum(I));
    Sy = sum(I,2)/max(sum(I,2));
    
    % We create an empty 3x3 tiled layout:
    %  1 2 3
    %  4 5 6
    %  7 8 9
    tiledlayout(3, 3);
    
    % Starting from the tile 1, we plot a 1x2 tile:
    %  1 2 x
    %  x x x
    %  x x x
    nexttile(1,[1 2])
    plot(Sx,'k.')
    % Starting from the tile 4, we plot a 2x2 tile:
    %  x x x
    %  4 5 x
    %  7 8 x
    nexttile(4,[2 2])
    imagesc(I)
    colormap(gray(256))
    % Starting from the tile 6, we plot a 2x1 tile:
    %  x x x
    %  x x 6
    %  x x 9
    nexttile(6,[2 1])
    plot(Sy,1:numel(Sy),'k.')
    

    Matlab 自动调整绘图的大小。

    我们得到:

    在引擎盖下,平铺布局如下所示:

    【讨论】:

      【解决方案4】:

      对于这种特殊情况,我建议直接使用低级axes 而不是高级subplot
      使用您创建的三个axes 对象的'OuterPosition' 属性将它们放置在适当大小的正确位置。

      【讨论】:

        【解决方案5】:

        如果您希望 图像(扭曲的图像)对齐:

        axis('image') 更改为axis('tight')

        如果您希望图像纵横比保持不变,并将轴与图像对齐:

        这又快又脏,但是在应用axis('tight') 之后,将图形调整到适当的比例...

        【讨论】:

        • 确实,这是最简单的解决方案,但是它会扭曲图像;我认为这不是 OP 想要的。
        • 对,图片没有合适的纵横比。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-11
        • 2015-06-27
        • 1970-01-01
        • 1970-01-01
        • 2012-11-23
        • 1970-01-01
        相关资源
        最近更新 更多