如何在Matlab中绘制非常低的负值

时间:2017-08-31 11:35:08

标签: matlab plot matlab-figure

我想绘制以下内容 - 见下文。

我想使用半学术的原因 - 或其他什么,也许你有建议? - 数据是如此之低,以至于所有正数据都显示为零。

当然,半决赛不适用于负面数据。但是我能做什么?目标是积极和消极数据在图中以某种方式显示为不同于零。

我看到了这个问题(Positive & Negitive Log10 Scale Y axis in Matlab),但有更简单的方法吗?

我对semilogy命令的另一个问题是数据被绘制成好像从11月到4月,而它们实际上是从1月到6月!

%% Date vector
Y = [];
for year = 2008:2016
    Y = vertcat(Y,[year;year]);
end
M = repmat([01;07],9,1);
D = [01];
vector = datetime(Y,M,D);

%% Data
operatingValue=...
   1.0e+05 *...
   [0.020080000000000,   0.000010000000000,   0.000430446606112,   0.000286376498540,   0.000013493575572,   0.000008797774209;...
    0.020080000000000,   0.000020000000000,   0.000586846360023,   0.000445575962649,   0.000118642085670,   0.000105982759202;...
    0.020090000000000,   0.000010000000000,   0.000304503221392,   0.000168068072591,  -0.000004277640797,   0.000006977580173;...
    0.020090000000000,   0.000020000000000,   0.000471819542315,   0.000318827321824,   0.000165018495621,   0.000188500216550;...
    0.020100000000000,   0.000010000000000,   0.000366527395452,   0.000218539902929,   0.000032265798656,   0.000038839492621;...
    0.020100000000000,   0.000020000000000,   0.000318807172600,   0.000170892065948,  -0.000093830970932,  -0.000096575559444;...
    0.020110000000000,   0.000010000000000,   0.000341114962826,   0.000187311222835,  -0.000118595282218,  -0.000135188693035;...
    0.020110000000000,   0.000020000000000,   0.000266317725166,   0.000128625220303,  -0.000314547081599,  -0.000392868178754;...
    0.020120000000000,   0.000010000000000,   0.000104302824558,  -0.000000079359646,  -0.001817533087893,  -0.002027417507676;...
    0.020120000000000,   0.000020000000000,   0.000093484465168,  -0.000019260661622,  -0.002180826237198,  -0.001955577709102;...
    0.020130000000000,   0.000010000000000,   0.000052921606827,  -0.000175185193313,  -4.034665389612666,  -4.573270848282296;...
    0.020130000000000,   0.000020000000000,   0.000027218083520,  -0.000167098897097,                   0,                   0;...
    0.020140000000000,   0.000010000000000,   0.000044907412504,  -0.000106127286095,  -0.012248660549809,  -0.010693498138601;...
    0.020140000000000,   0.000020000000000,   0.000061663936450,  -0.000070280400096,  -0.015180683545658,  -0.008942771925367;...
    0.020150000000000,   0.000010000000000,   0.000029214681162,  -0.000190870890021,                   0,                   0;...
    0.020150000000000,   0.000020000000000,   0.000082672707169,  -0.000031566292849,  -0.003226048850797,  -0.003527284081616;...
    0.020160000000000,   0.000010000000000,   0.000084562787728,  -0.000024916156477,  -0.001438488940835,  -0.000954872893879;...
    0.020160000000000,   0.000020000000000,   0.000178181932848,   0.000054988621755,  -0.000172520970578,  -0.000139835312255]

figure;
semilogy( datenum(vector), operatingValue(:,3), '-+', datenum(vector), operatingValue(:,4), '-o',...
    datenum(vector), operatingValue(:,5), '-*', datenum(vector), operatingValue(:,6), '-x',...
    'LineWidth',1.2 ), grid on;
dateaxis('x', 12);

1 个答案:

答案 0 :(得分:1)

将函数symlog保存在目录中。

 function symlog(varargin)
    % SYMLOG bi-symmetric logarithmic axes scaling
    %   SYMLOG applies a modified logarithm scale to the specified or current
    %   axes that handles negative values while maintaining continuity across
    %   zero. The transformation is defined in an article from the journal
    %   Measurement Science and Technology (Webber, 2012):
    %
    %     y = sign(x)*(log10(1+abs(x)/(10^C)))
    %
    %   where the scaling constant C determines the resolution of the data
    %   around zero. The smallest order of magnitude shown on either side of
    %   zero will be 10^ceil(C).
    %
    %   SYMLOG(ax=gca, var='xyz', C=0) applies this scaling to the axes named
    %   by letter in the specified axes using the default C of zero. Any of the
    %   inputs can be ommitted in which case the default values will be used.
    %
    %   SYMLOG uses the UserData attribute of the specified axes to record the
    %   current transformation applied so that subsequent calls to symlog
    %   operate on the original data rather than the newly transformed data.
    %
    % Example:
    %   x = linspace(-50,50,1e4+1);
    %   y1 = x;
    %   y2 = sin(x);
    %
    %   subplot(2,4,1)
    %   plot(x,y1,x,y2)
    %
    %   subplot(2,4,2)
    %   plot(x,y1,x,y2)
    %   set(gca,'XScale','log') % throws warning
    %
    %   subplot(2,4,3)
    %   plot(x,y1,x,y2)
    %   set(gca,'YScale','log') % throws warning
    %
    %   subplot(2,4,4)
    %   plot(x,y1,x,y2)
    %   set(gca,'XScale','log','YScale','log') % throws warning
    %
    %   subplot(2,4,6)
    %   plot(x,y1,x,y2)
    %   symlog('x')
    %
    %   s = subplot(2,4,7);
    %   plot(x,y1,x,y2)
    %   symlog(s,'y') % can but don't have to provide s.
    %
    %   subplot(2,4,8)
    %   plot(x,y1,x,y2)
    %   symlog() % no harm in letting symlog operate in z axis, too.
    %
    % Created by:
    %   Robert Perrotta
    %
    % Referencing:
    %   Webber, J. Beau W. "A Bi-Symmetric Log Transformation for Wide-Range
    %   Data." Measurement Science and Technology 24.2 (2012): 027001.
    %   Retrieved 6/28/2016 from
    %   https://kar.kent.ac.uk/32810/2/2012_Bi-symmetric-log-transformation_v5.pdf

    % default values
    ax = []; % don't call gca unless needed
    var = 'xyz';
    C = 0;

    % user-specified values
    for ii = 1:length(varargin)
        switch class(varargin{ii})
            case 'matlab.graphics.axis.Axes'
                ax = varargin{ii};
            case 'char'
                var = varargin{ii};
            case {'double','single'}
                C = varargin{ii};
            otherwise
                error('Don''t know what to do with input %d (type %s)!',ii,class(varargin{ii}))
        end
    end

    if isempty(ax) % user did not specify a value
        ax = gca;
    end

    % execute once per axis
    if length(var) > 1
        for ii = 1:length(var)
            symlog(ax,var(ii),C);
        end
        return
    end

    % From here on we redefine C to be 10^C
    C = 10^C;

    % Axes must be in linear scaling
    set(ax,[var,'Scale'],'linear')

    % Check for existing transformation
    userdata = get(ax,'UserData');
    if isfield(userdata,'symlog') && isfield(userdata.symlog,lower(var))
        lastC = userdata.symlog.(lower(var));
    else
        lastC = [];
    end
    userdata.symlog.(lower(var)) = C; % update with new value
    set(ax,'UserData',userdata)


    if strcmpi(get(ax,[var,'LimMode']),'manual')
        lim = get(ax,[var,'Lim']);
        lim = sign(lim).*log10(1+abs(lim)/C);
        set(ax,[var,'Lim'],lim)
    end

    % transform all objects in this plot into logarithmic coordiates
    transform_graph_objects(ax, var, C, lastC);

    % transform axes labels to match
    t0 = max(abs(get(ax,[var,'Lim']))); % MATLAB's automatically-chosen limits
    t0 = sign(t0)*C*(10.^(abs(t0))-1);
    t0 = sign(t0).*log10(abs(t0));
    t0 = ceil(log10(C)):ceil(t0); % use C to determine lowest resolution
    t1 = 10.^t0;

    mt1 = nan(1,8*(length(t1))); % 8 minor ticks between each tick
    for ii = 1:length(t0)
        scale = t1(ii)/10;
        mt1(8*(ii-1)+(1:8)) = t1(ii) - (8:-1:1)*scale;
    end

    % mirror over zero to get the negative ticks
    t0 = [fliplr(t0),-inf,t0];
    t1 = [-fliplr(t1),0,t1];
    mt1 = [-fliplr(mt1),mt1];

    % the location of our ticks in the transformed space
    t1 = sign(t1).*log10(1+abs(t1)/C);
    mt1 = sign(mt1).*log10(1+abs(mt1)/C);
    lbl = cell(size(t0));
    for ii = 1:length(t0)
        if t1(ii) == 0
            lbl{ii} = '0';
    % uncomment to display +/- 10^0 as +/- 1
    %     elseif t0(ii) == 0
    %         if t1(ii) < 0
    %             lbl{ii} = '-1';
    %         else
    %             lbl{ii} = '1';
    %         end
        elseif t1(ii) < 0
            lbl{ii} = ['-10^{',num2str(t0(ii)),'}'];
        elseif t1(ii) > 0
            lbl{ii} = ['10^{',num2str(t0(ii)),'}'];
        else
            lbl{ii} = '0';
        end
    end
    set(ax,[var,'Tick'],t1,[var,'TickLabel'],lbl)
    set(ax,[var,'MinorTick'],'on',[var,'MinorGrid'],'on')
    rl = get(ax,[var,'Ruler']);
    try
        set(rl,'MinorTick',mt1)
    catch err
        if strcmp(err.identifier,'MATLAB:datatypes:onoffboolean:IncorrectValue')
            set(rl,'MinorTickValues',mt1)
        else
            rethrow(err)
        end
    end



    function transform_graph_objects(ax, var, C, lastC)
    % transform all lines in this plot
    lines = findobj(ax,'Type','line');
    for ii = 1:length(lines)
        x = get(lines(ii),[var,'Data']);
        if ~isempty(lastC) % undo previous transformation
            x = sign(x).*lastC.*(10.^abs(x)-1);
        end
        x = sign(x).*log10(1+abs(x)/C);
        set(lines(ii),[var,'Data'],x)
    end

    % transform all Patches in this plot
    patches = findobj(ax,'Type','Patch');
    for ii = 1:length(patches)
        x = get(patches(ii),[var,'Data']);
        if ~isempty(lastC) % undo previous transformation
            x = sign(x).*lastC.*(10.^abs(x)-1);
        end
        x = sign(x).*log10(1+abs(x)/C);
        set(patches(ii),[var,'Data'],x)
    end

    % transform all Retangles in this plot
    rectangles = findobj(ax,'Type','Rectangle');
    for ii = 1:length(rectangles)
        q = get(rectangles(ii),'Position'); % [x y w h]
        switch var
            case 'x'
                x = [q(1) q(1)+q(3)]; % [x x+w]
            case 'y'
                x = [q(2) q(2)+q(4)]; % [y y+h]
        end
        if ~isempty(lastC) % undo previous transformation
            x = sign(x).*lastC.*(10.^abs(x)-1);
        end
        x = sign(x).*log10(1+abs(x)/C);

        switch var
            case 'x'
                q(1) = x(1);
                q(3) = x(2)-x(1);
            case 'y'
                q(2) = x(1);
                q(4) = x(2)-x(1);
        end

        set(rectangles(ii),'Position',q)
    end

最终绘制您的函数,包括symlog(gca,'y',-1.7)

plot( datenum(vector), operatingValue(:,3), '-+', datenum(vector), operatingValue(:,4), '-o',...
    datenum(vector), operatingValue(:,5), '-*', datenum(vector), operatingValue(:,6), '-x',...
    'LineWidth',1.2 ), grid on;
symlog(gca,'y',-1.7)

这是你的积极和消极价值的情节: Final plot

希望这能解决你的问题。