zoukankan      html  css  js  c++  java
  • 【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的原理还是有疑问的,暂时这样吧。

  • 相关阅读:
    【动态规划】多重背包
    【动态规划】完全背包问题
    【背包问题】0-1背包、完全背包、多重背包、混合三种背包、二位费用背包、分组背包
    HDU1712ACboy needs your help【分组背包】
    关于kettle
    面向接口编程
    MS Sql添加描述信息 及其他信息
    记录我一个特别酷的梦
    EF 线程内唯一对象
    javascript 学习犯错记录
  • 原文地址:https://www.cnblogs.com/shanchuan/p/8150316.html
Copyright © 2011-2022 走看看