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

  • 相关阅读:
    Security headers quick reference Learn more about headers that can keep your site safe and quickly look up the most important details.
    Missing dollar riddle
    Where Did the Other Dollar Go, Jeff?
    proteus 与 keil 联调
    cisco router nat
    router dhcp and dns listen
    配置802.1x在交换机的端口验证设置
    ASAv931安装&初始化及ASDM管理
    S5700与Cisco ACS做802.1x认证
    playwright
  • 原文地址:https://www.cnblogs.com/shanchuan/p/8150316.html
Copyright © 2011-2022 走看看