【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的原理还是有疑问的,暂时这样吧。

posted @ 2017-01-02 16:46  ssh_alitheia  阅读(2514)  评论(0编辑  收藏  举报