【Matlab】去除图片周围空白区域(plot subplot)
1. 原理
figure如同一张画布,axes是坐标轴用来控制所画图的位置和大小。
在matlab的帮助文档中Graphics->Formatting and Annotation->Coordinate System->Properties->Axes Properties有axes的属性,在Location and Size中可以看到主要有:
Position
TightInset
OuterPosition
下图是三者的关系,OuterPosition是外边框(红色虚线),Position是内边框(绿色实线),TightInset是有效边界(蓝色)与Position之间的部分(理解它才能自定义axes)。
图片引自matlab帮助手册。
2. plot画出来的图的空白边缘消除
Plot画出来的为单一的一张图,与之对应的是subplot,在一个figure中画多个图。消除Plot的空白区域有3种方法。
2.1
加一句命令即可:
set(gca,\'LooseInset\',get(gca,\'TightInset\'))
去除的不是很完全。
2.2
加一句命令即可:
set(gca,\'looseInset\',[0 0 0 0])
2.3
第3种要麻烦一些,我把它写成了一个函数,方便调用,如果您有需要,只需要在您的代码中使用该函数即可:
% RemovePlotWhiteArea: 去除Plot画的图的空白部分
% RemovePlotWhiteArea(gca)
% 输入
% gca: axes句柄
% author : TSC
% time : 2017-01-02
% email : 292936085#qq.com(将#替换为@)
function [] = RemovePlotWhiteArea(gca)
% TightInset的位置
inset_vectior = get(gca, \'TightInset\');
inset_x = inset_vectior(1);
inset_y = inset_vectior(2);
inset_w = inset_vectior(3);
inset_h = inset_vectior(4);
% OuterPosition的位置
outer_vector = get(gca, \'OuterPosition\');
pos_new_x = outer_vector(1) + inset_x; % 将Position的原点移到到TightInset的原点
pos_new_y = outer_vector(2) + inset_y;
pos_new_w = outer_vector(3) - inset_w - inset_x; % 重设Position的宽
pos_new_h = outer_vector(4) - inset_h - inset_y; % 重设Position的高
% 重设Position
set(gca, \'Position\', [pos_new_x, pos_new_y, pos_new_w, pos_new_h]);
2.4 结果
测试代码:
% 去除一张图片周围的空白区域
% *************************************************************************
remove_flag = 3; %1,2,3 任选一种查看效果
% -------------------------------------------------------------------------
x = 0:0.1:10;
y = sin(x);
figure(\'color\', [0.8, 0.8, 0.8]); % 为区分边界,将底色改为灰色
set(gcf, \'InvertHardCopy\', \'off\'); % 让设置的背景色有效
plot(x,y);
title(\'sinx\');
xlabel(\'x\');
ylabel(\'y\');
% 去除空白的第1种方式
if 1 == remove_flag
set(gca,\'LooseInset\',get(gca,\'TightInset\'))
end
% 去除空白的第2种方式
if 2 == remove_flag
set(gca,\'looseInset\',[0 0 0 0])
end
% 去除空白的第3种方式
if 3 == remove_flag
RemovePlotWhiteArea(gca);
end
set(gcf, \'PaperPositionMode\', \'auto\');
print(gcf, \'-djpeg\', \'-r300\', [\'respic/\', num2str(remove_flag), \'.jpg\']);
结果图片:
原图:
去除空白的第1种方式:
去除空白的第2种方式:
去除空白的第3种方式
3. subplot画出来的图的空白边缘消除
3.1 code
subplot以子图的形式画多幅图,所以有多少axes需要控制,比起plot要复杂一些。
原理是一样的,先把每个子图的位置和大小定下来,再设置每个子图里面axes的位置和大小,直接给出函数:
% RemoveSubplotWhiteArea: 去除subplot周围的空白部分
% RemoveSubplotWhiteArea(gca, sub_row, sub_col, current_row, current_col)
% 输入
% gca :axes句柄
% sub_row :subplot的行数
% sub_col :subplot的列数
% current_row :当前列数
% current_col :当前行数
%
% 注意:使用如下语句,print保存图片的时候使其按照设置来保存,否则修改无效
% set(gcf, \'PaperPositionMode\', \'auto\');
% author : TSC
% time : 2017-01-02
% email : 292936085#qq.com(将#替换为@)
function [] = RemoveSubplotWhiteArea(gca, sub_row, sub_col, current_row, current_col)
% 设置OuterPosition
sub_axes_x = current_col*1/sub_col - 1/sub_col;
sub_axes_y = 1-current_row*1/sub_row; % y是从上往下的
sub_axes_w = 1/sub_col;
sub_axes_h = 1/sub_row;
set(gca, \'OuterPosition\', [sub_axes_x, sub_axes_y, sub_axes_w, sub_axes_h]); % 重设OuterPosition
% TightInset的位置
inset_vectior = get(gca, \'TightInset\');
inset_x = inset_vectior(1);
inset_y = inset_vectior(2);
inset_w = inset_vectior(3);
inset_h = inset_vectior(4);
% OuterPosition的位置
outer_vector = get(gca, \'OuterPosition\');
pos_new_x = outer_vector(1) + inset_x; % 将Position的原点移到到TightInset的原点
pos_new_y = outer_vector(2) + inset_y;
pos_new_w = outer_vector(3) - inset_w - inset_x; % 重设Position的宽
pos_new_h = outer_vector(4) - inset_h - inset_y; % 重设Position的高
% 重设Position
set(gca, \'Position\', [pos_new_x, pos_new_y, pos_new_w, pos_new_h]);
3.2 结果
测试代码
% 去除subplot画出来的图的周围空白部分
x = 0:0.1:10;
y = sin(x);
figure(\'color\', [0.8, 0.8, 0.8], \'position\', [100, 100, 800,400]); % 为区分边界,将底色改为灰色
set(gcf, \'InvertHardCopy\', \'off\'); % 让设置的背景色有效
sub_row = 4; % 子图行数
sub_col = 4; % 子图列数
for i_row = 1 : sub_row
for j_col = 1 : sub_col
order = (i_row-1)*sub_col+j_col; % 子图的顺序
subplot(sub_row, sub_col, order);
plot(y);
title([num2str(i_row), num2str(j_col)]);
xlabel(\'x\');
ylabel(\'y\');
RemoveSubplotWhiteArea(gca, sub_row, sub_col, i_row, j_col); % 去除空白部分
end
end
set(gcf, \'PaperPositionMode\', \'auto\'); % 使print出来的与屏幕显示大小相同
print(gcf, \'-djpeg\', \'-r300\', [\'respic/sub\', num2str(sub_row), num2str(sub_col), \'.jpg\']);
结果图片
1行1列:
2行1列:
1行2列:
2行2列:
3行3列:
4行4列:
可以看到,3行3列和4行4列左边还是有一点点空白,我不能消除了,对axes的原理还是有疑问的,暂时这样吧。