zoukankan      html  css  js  c++  java
  • matlab subplot 的边距(with tight margins)

    matlab subplot的边距问题

    在matlab中使用subplot画出的图像的边距比较,因此,不管是在存为位图图像还是矢量图像的时候,这样的边距对后期结果的影响都比较麻烦。因此在网上找到了如下的解决方案:

    1. 使用subplot_tight函数。
    2. 使用set(gca, 'LooseInset', get(gca,'TightInset')), from here.

    一些来源及参考:

    1. Figure margins, subplot spacings, and more… » File Exchange Pick of the Week - MATLAB & Simulink
    2. matlab控制图像的边界(margin),subplot的间距(gap)_再干杨超越的博客-CSDN博客
    3. How to reduce the borders around subplots in matlab?

    新的解决方案

    但是这些都不是很方便,使用subplot_tight时,需要对Axes的句柄进行管理,而我在画图的时候,很多是时候并不需要其够本。而使用LooseInset则每次都需要在自己的代码里重复这一句,很麻烦。

    因此,写了如下的代码:文件名:tsubplot

    %=============================================================================
    %     FileName: tsubplot.m
    %         Desc: like subplot, but with the margin and gap being very small
    %       Author: Troy Daniel
    %        Email: Troy_Daniel@163.com
    %     HomePage: https://www.cnblogs.com/troy-daniel
    %      Version: 0.0.2
    %   LastChange: 2021-06-14 19:18:53
    %      History:
    % Ver 0.0.1     2021-06-14
    %				Initial delivery
    % Ver 0.0.2     2021-06-14
    % 				Return the Axes, if the bounding box are very close to the desired one
    %=============================================================================
    function h = tsubplot(varargin)
    	% Ver 0.0.1
    	%  +---------+---------+---------+
    	%  |    1    |     2   |    3    |
    	%  +---------+---------+---------+
    	%  |    4    |     5   |    6    |
    	%  +---------+---------+---------+
    	%  |    7    |     8   |    9    |
    	%  +---------+---------+---------+
        if nargin >= 3, nRow = varargin{1}, nCol = varargin{2}, nIndex = varargin{3}; end
    	if nargin == 2, error("Calling with two input args is not supported"), end
    	if nargin == 1
    		if varargin{1} < 100 || varargin{1} > 999
    			error("Invaild calling with one parameters");
    		end
    		nRow = floor(varargin{1} / 100);
    		nCol = floor(mod(varargin{1}, 100) / 10);
    		nIndex = mod(varargin{1}, 10);
    		if nIndex > (nRow * nCol)
    			error("Invaild calling with one parameters");
    		end
    	end
    
    	margin = 0.01;
    	gap = 0.01;
    	%     +------------------------------------------------------------------+
    	%     |          margin                           margin                 |
    	%     | m +------------------------+        +------------------------+ m |     +
    	%     | a |         1              |   gap  |          2             | a |     | h
    	%     | r +------------------------+        +------------------------+ r |     +
    	%     | g      gap                                 gap                 g |
    	%     | i +------------------------+        +------------------------+ i |
    	%     | n |         3              |        |          4             | n |
    	%     |   +------------------------+        +------------------------+   |
    	%     |          margin                           margin                 |
    	%     +------------------------------------------------------------------+
    	%         +------------------------+
    	%              w
    	w = (1-margin * 2 - gap * (nCol - 1)) / nCol;
    	h = (1-margin * 2 - gap * (nRow - 1)) / nRow;
    
    	cols = mod(nIndex-1, nCol) + 1;
    	colMin = min(cols);
    	colSpan = max(cols) - colMin + 1;
    	% colMax = max(cols);
    	rows = floor((nIndex-1)/nCol) + 1;
    	rowMin = min(rows);
    	rowSpan = max(rows) - rowMin + 1;
    	rowMax = max(rows);
    
    	outPosition =  [margin + (colMin-1) * (w + gap), ...
    			margin + (nRow - rowMax) * (h + gap), ...
    			w * colSpan + gap * (colSpan - 1), ...
    			h * rowSpan + gap * (rowSpan - 1)];
    	% h = axes('Units','normalized', ...
    	% 	'OuterPosition', [margin + (colMin-1) * (w + gap), ...
    	% 		margin + (nRow - rowMax) * (h + gap), ...
    	% 		w * colSpan + gap * (colSpan - 1), ...
    	% 		h * rowSpan + gap * (rowSpan - 1)]);
    
    	% remove axes that was covered by this axis
    	tolerance = 0.01;
    	outRect = [outPosition(1:2) - tolerance, outPosition(1:2) + outPosition(3:4) + tolerance];
    	fig = gcf;
    	nLength = length(fig.Children);
    	for idx = nLength:-1:1
    		hAxes = fig.Children(idx);
    		if class(hAxes) == "matlab.graphics.axis.Axes"
    			%  if the bounding box differ no more than tolerance, treat it as the desired axes
    			if all(abs(hAxes.OuterPosition(1:2)- outPosition(1:2)) < tolerance) && all(abs(hAxes.OuterPosition(3:4) + hAxes.OuterPosition(1:2) - (outPosition(3:4) + outPosition(1:2)))< tolerance) 
                    axes(hAxes); % make this the current active one
    				h = hAxes;
    				return;
    			end
    			if all(hAxes.Position(1:2)> outRect(1:2)) && all(hAxes.Position(3:4) + hAxes.Position(1:2) < outRect(3:4))
    				delete(hAxes);
    			end
    		end
    	end
    	h = axes('Units','normalized', 'OuterPosition', outPosition);
        set(h,'LooseInset',get(h,'TightInset'));   % Please refer to: https://undocumentedmatlab.com/articles/axes-looseinset-property
    end
    
    

    这个函数在使用的时候与matlab自带的subplot基本类似:

    t = 0:0.1:10;
    tsubplot(211);
    plot(t, sin(t), '-r');
    tsubplot(2,2,3);
    plot(t, cos(t), '--b');
    tsubplot(2,2,4);
    plot(sin(2*t), cos(3*t), '-b');
    
    % add again, draw on the first Axes
    tsubplot(2,1,1);
    hold on;
    t = 0: 1 : 10; 
    stem(t, sin(t), 'm');
    

    结果如下:

    当然,要修改margin与gap,直接在函数文件里修改即可。由于自用,就没有进一步封装了。

  • 相关阅读:
    ORA-06553:PLS-306:wrong number or types of arguments in call to ''
    ORA-06577:output parameter not a bind variable
    CSS3之边框属性border
    Linux_LAMP 最强大的动态网站解决方案
    Linux_LAMP 最强大的动态网站解决方案
    Field BSEG-MWSKZ . does not exist in the screen SAPMF05A 0300 Message no. 00349
    mysql group by
    perl 解析JSON
    数组的数组 散列的散列
    HTTP Cookies
  • 原文地址:https://www.cnblogs.com/troy-daniel/p/MatlabTightSubplot.html
Copyright © 2011-2022 走看看