对我之前版本的程序代码进行了改进:改正了一个小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
%%