MATLAB | 老版本如何更加优雅的调整子图空隙,去除白边?

本文介绍了如何在Matlab老版本中使用tsubplot函数优雅地调整子图的空隙,消除白边。tsubplot提供了'tight'、'compact'、'loose'三种模式来控制子图间隙,使得布局更加紧凑或松散。通过实例展示了不同模式下子图的显示效果,并给出了占据多块子图及单图的使用方法,帮助习惯使用subplot的老用户更好地布局图形。

老版本如何更加优雅的调整子图空隙,去除白边?标题如是说,之所以说是老版本,不是新版本用不了,而是因为比较新的版本的tiledlayout也能实现这些功能,

不过对于用惯了subplot函数的人,这里推出的tsubplot函数可能会更合大家胃口。老样子,先讲用法,工具函数放在最后。

效果

可以看到几乎完全没有白边。

函数使用

函数的基本使用形式为:

  • tsubplot(m,n,p,type)

m是网格行数,n是网格列数,p是网格位置这些和subplot一模一样。不同的是type属性可以控制间隙,以下是该属性可取的值:

  • ‘tight’ 几乎没有空隙
  • ‘compact’ 紧凑
  • ‘loose’ 较为松散

基本使用

type='tight';

tsubplot(2,2,1,type)
x=linspace(0,10);
y1=sin(x);
plot(x,y1,'LineWidth',1.5)
title('Subplot 1: sin(x)')

tsubplot(2,2,2,type)
y2=sin(2*x);
plot(x,y2,'LineWidth',1.5)
title('Subplot 2: sin(2x)')

tsubplot(2,2,3,type)
y2=sin(3*x);
plot(x,y2,'LineWidth',1.5)
title('Subplot 3: sin(3x)')

tsubplot(2,2,4,type)
y3=sin(4*x);
plot(x,y3,'LineWidth',1.5)
title('Subplot 4: sin(4x)') 

'tight’效果:

'compact’效果:

'loose’效果:

原始效果:

占据多块子图

type='tight';
[X,Y,Z]=peaks;

% 坐标区域块 1
tsubplot(2,3,1,type)
contour(X,Y,Z,15)

% 占据两行两列的坐标区域块
tsubplot(2,3,[2,3,5,6],type)
contourf(X,Y,Z,15)

% 坐标区域块 3
tsubplot(2,3,4,type)
imagesc(Z)

'tight’效果:

'compact’效果:

'loose’效果:

原始效果:

单图

tsubplot(1,1,1,'tight');

t=0.01:0.2:3*pi;
hold on;grid on
plot(t,cos(t)./(1+t),'LineWidth',2)
plot(t,sin(t)./(1+t),'LineWidth',2)
plot(t,cos(t+pi/2)./(1+t+pi/2),'LineWidth',2)
plot(t,cos(t+pi)./(1+t+pi),'LineWidth',2)
legend

'tight’效果:

原始效果:


工具函数完整代码

function ax=tsubplot(rows,cols,ind,type)
% @author : slandarer
% gzh  : slandarer随笔

if nargin<4,type='tight';end
sz=[rows,cols];
ratio1=[0,0,1,1];
switch type
    case 'tight'
        ratio1=[0,0,1,1];
        % ratio2=[0.031 0.054 0.9619 0.9254];
    case 'compact'
        ratio1=[0.034 0.0127 0.9256 0.9704];
        % ratio2=[0.065 0.0667 0.8875 0.8958];
    case 'loose'
        ratio1=[0.099 0.056 0.8131 0.8896];
        % ratio2=[0.13 0.11 0.775 0.815];
end
k=1;
posList=zeros(sz(1)*sz(2),4);
for i=1:sz(1)
    for j=1:sz(2)
        tpos=[(j-1)/sz(2),(sz(1)-i)/sz(1),1/sz(2),1/sz(1)];
        posList(k,:)=[tpos(1)+tpos(3).*ratio1(1),tpos(2)+tpos(4).*ratio1(2),...
                      tpos(3).*ratio1(3),tpos(4).*ratio1(4)];
        k=k+1;
    end
end
posSet=posList(ind(:),:);
xmin=min(posSet(:,1));
ymin=min(posSet(:,2));
xmax=max(posSet(:,1)+posSet(:,3));
ymax=max(posSet(:,2)+posSet(:,4));
ax=axes('Parent',gcf,'LooseInset',[0,0,0,0],...
    'OuterPosition',[xmin,ymin,xmax-xmin,ymax-ymin]);
% @author : slandarer
% gzh  : slandarer随笔
end
<think>好的,我现在需要帮用户解决如何在MATLAB中动态调整间距的问题。用户提到了“动态调整”,所以可能需要一个灵活的方法,而不是手动一个个修改。首先,我得回忆一下自己知道的MATLAB绘图相关函数。 用户提供的引用里提到了几种方法,比如tight_subplot、tiledlayout(适用于2019b及以上版本),还有subplots_adjust。不过这些引用中,引用[1]和[4]提到的是MATLAB的方法,而引用[2]和[3]是关于matplotlib的,可能用户混淆了,但问题集中在MATLAB上,所以需要专注于MATLAB的解决方案。 首先,tight_subplot函数。我记得这不是MATLAB内置的函数,而是第三方提供的,可能需要从File Exchange下载。这个函数允许用户设置之间的间距,可能通过参数调整。用户提到的动态调整可能需要通过调整输入参数来实现,比如在生成时指定间距。 然后是tiledlayout,这个函数在较新的版本(2019b以后)才有。它提供了更灵活的布局控制,比如Padding和TileSpacing属性。用户可以使用tiledlayout创建布局,然后用nexttile添加调整间距可以通过修改TileSpacing属性为'compact'、'loose'或'none',或者自定义间距值。这可能更符合动态调整的需求,因为可以在生成形后修改属性,实时更新布局。 另外,subplot本身的调整可能比较困难,但引用[3]中的subplots_adjust其实是matplotlib的函数,但MATLAB中是否有类似功能呢?在MATLAB中,可以通过设置figure的Position属性,或者使用subplot的Position参数手动调整每个的位置,但这种方法比较繁琐,不够动态。 接下来需要确认用户的具体需求。动态调整可能意味着在生成形后,根据数据或用户输入自动调整间距,或者在程序运行时交互式地调整。例如,在循环中生成多个,根据的数量自动调整间距。 对于tight_subplot的使用,需要找到该函数的代码,并查看其参数。比如,tight_subplot(Nh, Nw, gap, marg_h, marg_w)中的gap参数控制水平和垂直间距,marg_h和marg_w控制边缘距离。用户可以在调用时动态传入不同的gap值,从而调整间距。 对于tiledlayout,调整TileSpacing和Padding属性可以在创建布局时指定,或者在之后修改。例如: t = tiledlayout(2,2); t.TileSpacing = 'compact'; t.Padding = 'tight'; 或者设置具体的数值,比如: t.TileSpacing = 'none'; t.TileSpacing = 0.1; % 可能不支持,需要查文档 但需要确认MATLAB是否允许数值调整。根据文档,TileSpacing的选项是预定义的,如'loose'(默认)、'compact'、'tight',可能不支持自定义数值。这样的话,动态调整的灵活性可能受限,只能在这几个选项之间切换。但如果是这样的话,可能无法做到连续调整间距,只能选择不同的预设模式。 那么,是否还有其他方法?比如,使用subplot创建后,获取每个axes的位置,然后重新计算并设置它们的Position属性。例如,在生成所有后,遍历每个axes,根据所需的间距动态计算新的位置,并设置其Position。这种方法需要较多的代码,但可以实现动态调整。 例如,假设有4,排列成2x2,可以通过计算每个的左下角坐标和宽度、高度,考虑间距后重新分配位置。但这种方法需要处理多个参数,容易出错,但灵活性高。 结合用户提供的引用,引用[1]提到了tight_subplot和tiledlayout,而引用[4]提到tiledlayout的帮助链接。所以,可能最佳的方法是使用tiledlayout(如果版本支持),或者使用tight_subplot函数。 现在需要给出具体的代码示例。比如,使用tiledlayout: % 创建布局 t = tiledlayout(2, 2); t.TileSpacing = 'compact'; % 减少间距 t.Padding = 'tight'; % 减少边缘空白 % 添加 nexttile; plot(rand(10,1)); nexttile; plot(rand(10,1)); nexttile; plot(rand(10,1)); nexttile; plot(rand(10,1)); 这样,TileSpacing和Padding的设置会影响所有的间距和边缘。如果需要动态调整,可以在任何时候修改这些属性,然后刷新形。例如,在回调函数中根据用户输入修改属性值。 对于tight_subplot的使用,需要先下载该函数,然后调用: % 下载tight_subplot.m并添加到路径 % 示例代码 gap = [0.05 0.05]; % 水平和垂直间距 marg_h = [0.1 0.1]; % 上下边缘 marg_w = [0.1 0.1]; % 左右边缘 ha = tight_subplot(2,2, gap, marg_h, marg_w); for i = 1:4 axes(ha(i)); plot(rand(10,1)); end 这里的gap参数可以动态调整,比如根据输入参数改变,从而实现动态调整间距。 另外,用户提到动态调整,可能需要交互式调整,比如使用滑块控件来调整间距。这需要结合GUI编程。例如,创建一个滑块,当滑块值改变时,重新计算间距并更新位置。这可能需要更复杂的代码,比如使用uicontrol和回调函数。 例如,使用tiledlayout: % 创建figure和布局 fig = figure; t = tiledlayout(fig, 2,2); t.TileSpacing = 'compact'; % 添加滑块 slider = uicontrol('Style', 'slider', 'Min',0, 'Max',0.2, 'Value',0.05, ... 'Position', [100 20 120 20], 'Callback', @updateSpacing); function updateSpacing(source,~) gap = source.Value; t.TileSpacing = gap; % 这里可能需要检查是否允许数值输入 end 但根据MATLAB文档,TileSpacing属性可能只接受预设的字符串,如'compact',而不是数值。因此,这种方法可能不可行。这时候可能需要另一种方法,比如使用Position属性手动调整每个的位置。 另一种思路是,在生成后,使用subplot的Position参数。例如: figure; subplot(2,2,1); plot(rand(10,1)); subplot(2,2,2); plot(rand(10,1)); subplot(2,2,3); plot(rand(10,1)); subplot(2,2,4); plot(rand(10,1)); % 动态调整间距 new_hspace = 0.1; % 水平间距 new_vspace = 0.1; % 垂直间距 % 获取所有的句柄 ax = findobj(gcf, 'Type', 'axes'); % 重新计算每个的Position % 需要根据的排列和间距进行调整 % 例如,对于2x2的,每个的宽度和高度为 (1 - 2*margin - (n-1)*spacing)/n % 这里可能需要更复杂的计算 这种方式需要根据的行列数和当前figure的大小,计算每个的位置,并设置其Position属性。这可能比较复杂,但可以实现动态调整。 总结可能的解决方案: 1. 使用tiledlayout(推荐,如果版本支持),通过设置TileSpacing和Padding属性动态调整。 2. 使用tight_subplot函数,通过调整输入参数动态控制间距。 3. 手动调整每个的Position属性,适用于需要精细控制的情况。 4. 结合GUI控件实现交互式调整,但需要更复杂的编程。 在回答中,应该优先推荐tiledlayout和tight_subplot,并提供代码示例。同时,提到手动调整Position的方法作为备选方案,但指出其复杂性。 最后,需要确保引用正确的来源,比如引用[1]和[4]提到的tight_subplot和tiledlayout,而引用[3]中的subplots_adjust是matplotlib的,不在MATLAB中使用。</think>在MATLAB中动态调整间距的常用方法主要有以下三种,具体实现方式如下: ### 一、使用`tiledlayout`函数(推荐,适用于MATLAB 2019b及以上版本) 通过`TileSpacing`和`Padding`属性动态控制间距: ```matlab % 创建布局对象 t = tiledlayout(2, 2); % 2行2列 t.TileSpacing = 'compact'; % 减小间距 t.Padding = 'tight'; % 减少边缘空白 % 添加 nexttile; plot(rand(10,1)); nexttile; plot(sin(0:0.1:2*pi)); nexttile; imagesc(peaks); nexttile; bar(1:10); ``` 通过修改`TileSpacing`的预设值(`'loose'`/`'compact'`/`'tight'`)可快速调整间距[^1][^4]。 --- ### 二、使用`tight_subplot`函数(兼容旧版本) 从MATLAB File Exchange下载并调用第三方函数`tight_subplot.m`[^1]: ```matlab % 定义动态参数 rows = 2; cols = 2; horizontal_gap = 0.02; % 水平间距 vertical_gap = 0.03; % 垂直间距 margin = [0.05 0.05]; % 边缘距离[上下 左右] % 创建自适应 ha = tight_subplot(rows, cols, [vertical_gap horizontal_gap], margin); % 填充内容 for i = 1:rows*cols axes(ha(i)); plot(randn(100,1)); end ``` 通过调整`horizontal_gap`和`vertical_gap`的数值实现动态控制[^1]。 --- ### 三、手动调整`Position`属性(精细控制) 直接操作的坐标位置参数: ```matlab figure; subplot(2,2,1); plot(rand(10,1)); subplot(2,2,2); plot(peaks); subplot(2,2,3); stem(1:10); subplot(2,2,4); histogram(randn(1000,1)); % 动态计算新位置 new_hspace = 0.1; % 水平间距比例 new_vspace = 0.15; % 垂直间距比例 ax = findobj(gcf, 'Type', 'axes'); % 遍历所有重新分配位置 for i = 1:length(ax) [row, col] = ind2sub([2 2], i); % 根据实际行列数修改 pos_x = (col-1)*(1/cols) + (col-1)*new_hspace/cols; pos_y = 1 - row*(1/rows) - (row-1)*new_vspace/rows; set(ax(i), 'Position', [pos_x pos_y 1/cols-new_hspace 1/rows-new_vspace]); end ``` --- ### 方法对比 | 方法 | 优点 | 局限性 | |-------------------|-------------------------------|---------------------------| | `tiledlayout` | 语法简洁,支持动态属性修改 | 仅适用于MATLAB 2019b+ | | `tight_subplot` | 兼容旧版本,参数灵活 | 需额外下载第三方函数 | | 手动调整`Position`| 完全控制布局细节 | 代码复杂,需自行计算坐标 | ---
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

slandarer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值