【Matlab】數據放大鏡

通常,當要顯示的數據的範圍較大時,通常會將數據的某個局部細節就無法仔細觀察,這個時候,如果能夠放大某個局部,那麼將會非常好。下圖是筆者在MathWorks上面看到的一個很棒的帶有數據局部放大窗口功能的工具箱。

官方給出的工具箱實現代碼如下: 

function MagInset(h, ax, ZoomArea, InsetPos, Lines)
    % ************ MagInset.m *************
    % * Created: January 1, 2015          *
    % * By: Damien Frost                  *
    % * Inspiration By: Robert Richardson *
    % *************************************
    % 
    % MagInset (Magnified Inset) places an axes inset into an existing 
    % figure with handle h. Re-size your figure and axes before running
    % MagInset.
    %
    % h - handle to a figure on which to place an inset
    %
    % ax - handle to an axes object. Set to -1 to use the default axes in the
    %      figure.
    %
    % ZoomArea - a 4x1 array which defines the zoom area that inset
    %            should have. It is of the form: 
    %                [xmin xmax ymin ymax]
    %            The values are NOT normalized values, but graph values. In
    %            this way, you can easily read off the zoom area you would like
    %            to specify.
    %
    % InsetPos - defines the position of the inset. It is of the form:
    %                [xmin xmax ymin ymax]
    %            The values are NOT normalized values, but graph values. In
    %            this way, you can easily read off the inset area you would
    %            like to specify
    %
    % Lines - defines a list of lines to connect the zoom area with the inset
    %         graph. It can be empty. It should be of the form:
    %             Lines = {'NW','SW'; 'NE','SE'};
    %         It can have as many rows as you wish
    %         The first colum is the corner of the Zoom Area. The second column is the
    %         corner of the Inset Axes
    BadInput = 0;
    axesObjs = get(h, 'Children');  %axes handles
    % Determine which axes the inset will be placed on:
    if(ax == -1)
        MainAx = axesObjs(end);
    else
        MainAx = -1;
        for ii=1:1:max(size(axesObjs))
            if(axesObjs(ii) == ax)
                MainAx = axesObjs(ii);
                break;
            end
        end
        if(MainAx == -1)
            % Could not find the desired axes:
            fprintf('\nMagInset Error: Could not find the desired axes in the figure.\n');
            BadInput = 1;
        end
    end
    if(BadInput == 0)
        % Get the plot data:
        dataObjs = get(MainAx, 'Children');
        % Annotation positions are of the form:
        % [x y length height]
        % And are normalized to the figure
        % Calculate the normalize rectangular coordinates for the zoom area:
        [zax, zay] = xy2norm(MainAx, ZoomArea(1:2), ZoomArea(3:4));
        % Create the rectangle around the area we are going to zoom into:
        annotation('rectangle',[zax(1) zay(1) (zax(2) - zax(1)) (zay(2) - zay(1))]);
        % Calculate the inset position in normalized coordinates;
        [ipx, ipy] = xy2norm(MainAx, InsetPos(1:2), InsetPos(3:4));
        if(nargin > 4)
            % Add the lines from the zoom area to the inset:
            numLine = size(Lines,1);
            if((numLine>0) && (size(Lines,2) == 2))
                lx = zeros(2,1);
                ly = zeros(2,1);
                for ii=1:1:numLine
                    jj = 1;
                    % Find the co-ordinate in the zoom area:
                    % y co-ordinates:
                    if(Lines{ii,jj}(1) == 'S')
                        ly(jj) = zay(1);
                    else
                        ly(jj) = zay(2);
                    end
                    % x co-ordinates:
                    if(Lines{ii,jj}(2) == 'W')
                        lx(jj) = zax(1);
                    else
                        lx(jj) = zax(2);
                    end
                    jj = 2;
                    % Find the co-ordinate in the inset axes:
                    % y co-ordinates:
                    if(Lines{ii,jj}(1) == 'S')
                        ly(jj) = ipy(1);
                    else
                        ly(jj) = ipy(2);
                    end
                    % x co-ordinates:
                    if(Lines{ii,jj}(2) == 'W')
                        lx(jj) = ipx(1);
                    else
                        lx(jj) = ipx(2);
                    end
                    % Add the line:
                    annotation('line', lx,ly);
                end
            end
        end
        % Add the second set of axes on the same plot:
        iaxes = axes('position', [ipx(1) ipy(1) (ipx(2) - ipx(1)) (ipy(2) - ipy(1))]);
        hold on;
        box on;
        % Add the plots from the original axes onto the inset axes:
        copyobj(dataObjs,iaxes);
        % set the limits on the new axes:
        xlim(ZoomArea(1:2));
        ylim(ZoomArea(3:4));
        % Our work here is done.
    end
end
function [xn, yn] = xy2norm(axh, x, y)
    % ********* xy2norm.m *********
    % * Created: January 1, 2015  *
    % * By: Damien Frost          *
    % *****************************
    % This function takes a point (x, y) and returns the normalized
    % co-ordinates (xn, yn) given the axes with handle axh.
    %
    % *** Modifications: ***
    % 1) Added 'axh = handle(axh);' line to make the script backwards
    % compatible with MATLAB R2013a (Perhaps further back) - Thanks Shi
    % Zhao!
    axh = handle(axh);
    % Save some temporary variables about the axes:
    axPos = axh.Position;
    xlims = axh.XLim;
    ylims = axh.YLim;
    % Calculate the normalized co-ordinates:
    xn = axPos(1) + axPos(3) .* (x-xlims(1))./(xlims(2) - xlims(1));
    yn = axPos(2) + axPos(4) .* (y-ylims(1))./(ylims(2) - ylims(1));
    % GTFO:
end

要畫出上面兩幅圖片的效果,可以使用如下的兩個腳本實現: 

% An example of how to use MagInset.m
clear all;
% **************************************
% * Example 1: Single axes on a figure *
% **************************************
% Create a figure with a sine wave with random noise on it:
h1 = figure;
title('Single Axes MagInset Example');
hold on;
f0 = 10000;
t = 0:(1/f0)/1000:((1/f0)*2);
y = 5*sin(2*pi*f0*t) + rand(size(t));
plot(t*1000, y);
grid on;
xlabel('Time (ms)');
ylabel('Amplitude (V)');
% It is important to set the figure size and limits BEFORE running
% MagInset!
xlim([t(1) t(end)]*1000);
ylim([-6 10]);
% Once happy with your figure, add an inset:
MagInset(h1, -1, [0.04 0.045 1 4], [0.05 0.09 5.5 9], {'NW','NW';'SE','SE'});
% ****************************************
% * Example 2: Multiple axes in a figure *
% ****************************************
% Create a figure with a sine and cosine wave with random noise on it:
h2 = figure;
% Sine Wave:
ax(1) = subplot(2,1,1);
title(sprintf('MagInset Example with Subplots\n'));
hold on;
f0 = 10000;
t = 0:(1/f0)/1000:((1/f0)*2);
y = 5*sin(2*pi*f0*t) + rand(size(t));
plot(t*1000, y);
grid on;
xlabel('Time (ms)');
ylabel('Amplitude (V)');
xlim([t(1) t(end)]*1000);
ylim([-6 10]);
% Cosine Wave:
ax(2) = subplot(2,1,2);
hold on;
y = 5*cos(2*pi*f0*t) + rand(size(t));
plot(t*1000, y,'r');
grid on;
xlabel('Time (ms)');
ylabel('Amplitude (V)');
xlim([t(1) t(end)]*1000);
ylim([-6 10]);
% Link the x axes:
linkaxes(ax,'x');
% Once happy with your figure, add an inset:
% Cosine inset:
MagInset(h2, ax(1), [0.04 0.045 1 4], [0.05 0.09 5.5 9], {'NW','NW';'SE','SE'});
% Sine insets:
MagInset(h2, ax(2), [0.015 0.02 1.5 4], [0.038 0.078 5.5 9], {'NW','NW';'SE','SE'});
MagInset(h2, ax(2), [0.18 0.185 1.5 4], [0.125 0.165 5.5 9], {'NE','NE';'SW','SW'});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章