MATLAB:简便函数MakeSubplotTight(),消除Subplot绘制的图片四周空白区域,使图片紧凑tight

对我之前版本的程序代码进行了改进:改正了一个小bug,使函数只需3个基本参数输入即可方便使用,增加了6个可选参数使之可以个性化修改,也使之兼容更早期的MATLAB2010版本。
我上一次版本的程序:点此浏览

思路来源:
matlab绘制图片时需要存储用于word文章编辑中,而存储的图片空白区域较大(相对图片实际内容而言占据太多空间),需要在word中手动裁剪。
在写论文或报告时图片较多时需要重复手动裁剪,且不易保证每张图片大小调整得一致。
为此,需要利用程序自动消除空白区域并自动保存图片,确保所有图片紧凑且大小一致。

函数:MakeSubplotTight(Hgcf,Nrow,Ncol)
%函数说明:通过调整figure中坐标轴大小和位置,使figure的空白区域减少,使曲线图更紧凑
% 在matlab2010b和matlab2018a中均经过测试,应该可适用于所有2010后的版本
%参数: 最少需要3个参数,还有6个可选参数
% Hgcf (必填参数) 要剔除空白区域的图片figure的句柄
% Nrow (必填参数) subplot(或plot )中子图的行数
% Ncol (必填参数) subplot(或plot )中子图的列数

函数应用效果图:
在这里插入图片描述

函数较长,可以点此下载代码文件:
下载地址

下面附演示程序代码:

clc
close all
clear all
XY=load('XY.txt');
X=XY(1:25,:);
Y=XY(26:50,:);
%绘制figure
NRow=5;
NCol=5;
Hgcf=figure();
for i=1:NRow
    for j=1:NCol
        Ncount=NCol*(i-1)+j;
        subplot(NRow,NCol,Ncount);
        plot(X(Ncount,:),Y(Ncount,:),'r');
        xlabel(strcat('X',num2str(Ncount)),'fontsize',12);ylabel(strcat('Y',num2str(Ncount)),'fontsize',12);
        title(strcat('图',num2str(Ncount)),'fontsize',14);
        legend(strcat('Y',num2str(Ncount)));
    end
end
%--------------设置图片大小----------------------
set(gcf,'units','pixel');
set(gcf,'position',[300  50  900 800]) 
% --------------自动保存修改前的图片----------------------
set(gcf, 'PaperPositionMode', 'auto');
print(gcf,'-dtiff','-r300','原始图片.png');
%--------------消除空白区域----------------------
 MakeSubplotTight(Hgcf,NRow,NCol);    %或者MakeSubplotTight(gcf,NRow,NCol);
 % --------------自动保存修改后的图片----------------------
set(Hgcf, 'PaperPositionMode', 'auto');
print(Hgcf,'-dtiff','-r300','消除空白区域后的图片.png');

下面附函数详细代码:

function [] = MakeSubplotTight(Hgcf,Nrow,Ncol,MarginLeft,MarginRight,MarginTop,MarginBottom,GapRow,GapCol)
%%
%***********************************************************************
%函数说明:通过调整figure中坐标轴大小和位置,使figure的空白区域减少,使曲线图更紧凑
%参数:   最少需要3个参数,还有6个可选参数
%         Hgcf      (必填参数)           要剔除空白区域的图片figure的句柄
%         Nrow      (必填参数)           subplot(或plot )中子图的行数
%         Ncol      (必填参数)           subplot(或plot )中子图的列数
%         MarginLeft     (可选参数)      左边留白区域,范围0~0.99,默认0.01
%         MarginRight    (可选参数)      右方留白区域,范围0~0.99,默认0.01
%         MarginTop      (可选参数)      上方留白区域,范围0~0.99,默认0.01
%         MarginBottom   (可选参数)      下方留白区域,范围0~0.99,默认0.01
%         GapRow         (可选参数)      行与行之间的空白间距,范围0~0.99,默认0.0
%         GapCol         (可选参数)      列与列之间的空白间距,范围0~0.99,默认0.0
%***********************************************************************
%%
%------------输入参数处理,包括给定默认图片四周留白和给定行与行、列与列的TightInset边界之间的间隙------------------
if nargin<3
   disp('输入参数过少!');
end
if nargin<4
  MarginLeft=0.01;
  MarginRight=0.01;
  MarginTop=0.01;
  MarginBottom=0.01;
  GapRow=0;
  GapCol=0;
end
if nargin<5
  MarginRight=0.01;
  MarginTop=0.01;
  MarginBottom=0.01;
  GapRow=0;
  GapCol=0;
end
if nargin<6
  MarginTop=0.01;
  MarginBottom=0.01;
  GapRow=0;
  GapCol=0;
end
if nargin<7
  MarginBottom=0.01;
  GapRow=0;
  GapCol=0;
end    
if nargin<8
  GapRow=0;
  GapCol=0;
end    
if nargin<9
  GapCol=0;
end  
if nargin>9
    disp('输入参数过多!');
end

%%
% % %--------------创建一个Nrow*Ncol的axes数组,用于存储subplot的axes句柄------------------------
% TempFigure=figure('visible','off');
% axes;% axes(TempFigure);
% for i=1:Nrow
%     for j=1:Ncol
%        Axes(i,j)=gca;  
%     end
% end   
% close(TempFigure);

% %--------------自动获得subplot的各个axes,并且将其赋给Axes数组------------------------
HandleAxesTemp=findobj(Hgcf,'type','axes');  %列向量,元素从前到后依次对应从右往左、从下到上的subplot的axes(matlab2010b中未区分axes和legend,使用legend命令时创造的也是axes对象,但axes.Tag='',legend.Tag=‘legend’)
HandleAxesTemp=flipud(HandleAxesTemp);       %将向量元素倒序排列,即素从前到后依次对应从左往右、从上到下的subplot的axes(包括legend)
HandleAxes=findobj(Hgcf,'type','axes'); 
HandleAxes=flipud(HandleAxes);
j=1;
for i=1:length(HandleAxesTemp)   %只存储非legend创造的axes
    if( isempty(get(HandleAxesTemp(i),'Tag')) )  %  如果axes对象不是legend,    if(  get(HandleAxesTemp(i),'Tag')=='legend' )
        HandleAxes(j)=HandleAxesTemp(i);
        j=j+1;
    else  %  如果axes对象实际legend,则get(HandleAxesTemp(i),'Tag')=='legend',即不为空
        ;    %不执行操作
    end          
end
Ncount=1;
for i=1:Nrow
    for j=1:Ncol
        axes(HandleAxes(Ncount));   %This command also makes current axes the first object listed in the Children property of the figure and sets the CurrentAxes property of the figure to current axes
        Axes(i,j)=gca;
        Ncount=Ncount+1;        
    end
end   
% %--------------自动获得subplot的各个axes,并且进行赋值------------------------
% HandleAxes=findobj(Hgcf,'type','axes');  %列向量,元素从前到后依次对应从右往左、从下到上的subplot的axes
% Ncount=1;
% for i=Nrow:-1:1
%     for j=Ncol:-1:1
%         axes(HandleAxes(Ncount));   %This command also makes current axes the first object listed in the Children property of the figure and sets the CurrentAxes property of the figure to current axes
%         Axes(i,j)=gca;
%         Ncount=Ncount+1;        
%     end
% end   
 %%  
 %-----------------------获得每个坐标轴的TightInset的大小及坐标轴之间的最小间距-------------------------    
 %计算并存储列与列之间的每个subplot的TightInset  
 TightInsetSpaceCol=zeros(Nrow,Ncol+1);   %定义各列之间的TightInset间距存储矩阵
    for j=1:Ncol+1  
         for i=1:Nrow  
            if(j==1)
                TempA=get(Axes(i,1),'TightInset');  %TightInset——element vector of the form [left bottom right top]
                TightInsetSpaceCol(i,j)=TempA(1);
            elseif(1<j  && j<Ncol+1)
                TempA=get(Axes(i,j-1),'TightInset');
                TempB=get(Axes(i,j),'TightInset');               
                TightInsetSpaceCol(i,j)=TempA(3)+TempB(1);
            elseif(j==Ncol+1)
                TempA=get(Axes(i,Ncol),'TightInset');                       
                TightInsetSpaceCol(i,j)=TempA(3);
            end
        end 
    end   
    MaxTightInsetCol=zeros(1,Ncol+1);    %各列的图与图之间TightInset最大值,后续设置坐标轴位置时还会用到
    for j=1:Ncol+1  
       MaxTightInsetCol(j)=max(TightInsetSpaceCol(:,j));
    end 
    MaxTightInsetWidth=sum(MaxTightInsetCol);    %TightInset沿宽度方向所必需的面积(每列的最大TightInset之和)
 %计算并存储行与行之间的每个subplot的TightInset      
	TightInsetSpaceRow=zeros(Nrow+1,Ncol);     %定义各行之间的TightInset间距存储矩阵
       for i=1:Nrow+1  
        for j=1:Ncol         
            if(i==1)
                TempA=get(Axes(1,j),'TightInset');    
                TightInsetSpaceRow(i,j)=TempA(4);
            elseif(1<i  && i<Nrow+1)
                TempA=get(Axes(i-1,j),'TightInset');                    
                TempB=get(Axes(i,j),'TightInset');    
                TightInsetSpaceRow(i,j)=TempA(2)+TempB(4);
            elseif(i==Nrow+1)
                 TempA=get(Axes(Nrow,j),'TightInset');                  
                 TightInsetSpaceRow(i,j)=TempA(2);
            end
        end 
       end   
    MaxTightInsetRow=zeros(Nrow+1,1);    %各行的图与图之间TightInset最大值,后续设置坐标轴位置时还会用到
    for i=1:Nrow+1  
       MaxTightInsetRow(i)=max(TightInsetSpaceRow(i,:));
    end 
    MaxTightInsetHeight=sum(MaxTightInsetRow);    %TightInset沿宽度方向所必需的面积(每行的最大TightInset之和)
    %% 
%----------------------调整各个坐标轴axes的宽度和高度,使除去MaxTightInset和Gap之外的剩余空间被填满-----------------------------------
AxisSpaceWidth=1-MarginLeft-MarginRight-GapCol*(Ncol-1)-MaxTightInsetWidth;  %绘图坐标轴可用宽度
AxisSpaceHeight=1-MarginBottom-MarginTop-GapRow*(Nrow-1)-MaxTightInsetHeight;  %绘图坐标轴可用高度
PerAxisWidth=AxisSpaceWidth/Ncol;  %单个坐标轴宽度
PerAxisHeight=AxisSpaceHeight/Nrow;  %单个坐标轴高度
%调整每个坐标轴axes的宽度和高度
    for i=1:Nrow   
        for j=1:Ncol
           TempA=get(Axes(i,j),'Position');    % position ——[left bottom width height]
           TempA(3)=PerAxisWidth; 
           TempA(4)=PerAxisHeight;
           set(Axes(i,j),'Position',TempA);
        end 
    end  
    %%
% % %----------------------调整坐标轴位置,使各子图达到最终位置-----------------------------------    
%设置每个坐标轴axes的水平位置   
       for j=1:Ncol
        for i=1:Nrow 
            if(j==1)   %第一列
               TempA=get(Axes(i,j),'Position');   
               TempA(1)=MarginLeft+MaxTightInsetCol(1); 
               set(Axes(i,j),'Position',TempA);
            else      %其他列
               TempA=get(Axes(i,j),'Position');   
               TempB=get(Axes(i,j-1),'Position');                  
               TempA(1)=TempB(1)+PerAxisWidth+MaxTightInsetCol(j)+GapCol; 
               set(Axes(i,j),'Position',TempA);
            end
        end 
     end   
%调整每个坐标轴axes的垂直位置 
     for i=Nrow:-1:1   
        for j=Ncol:-1:1
            if(i==Nrow)    %最后一行
               TempA=get(Axes(i,j),'Position');    
               TempA(2)=MarginBottom+MaxTightInsetRow(Nrow+1);
               set(Axes(i,j),'Position',TempA);
            else         %其他行
               TempA=get(Axes(i,j),'Position');   
               TempB=get(Axes(i+1,j),'Position');   
               TempA(2)=TempB(2)+PerAxisHeight+MaxTightInsetRow(i+1)+GapRow; 
               set(Axes(i,j),'Position',TempA);
            end
        end 
     end
%% 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值