2017-08-31 97 views
0

我想绘制以下内容 - 请参见下文。如何在Matlab中绘制非常低的负值

我想使用semilogy的原因 - 或者别的什么,也许你有什么建议? - 数据是如此之低以至于所有的正面数据看起来都是零。

当然semilogy不适用于负数据。但我能做什么呢?我们的目标是,正面和负面的数据在图表中以某种方式可见,不同于零。

我看到了这个问题(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

做一个只有正面的副图,并且只有负面的副图才会翻转,缩放到相同的xlims。 – Oleg

+2

[在Matlab中正负号Log10标度Y轴]可能的副本(https://stackoverflow.com/questions/21027269/positive-negitive-log10-scale-y-axis-in-matlab) – Adriaan

回答

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

希望这能解决你的问题。

+6

此功能看起来像什么OP希望如此伟大。但是,当您使用文件交换中的函数时,很有必要在其所到期的地方提供信用。以下是该函数的文件交换页面的链接:[symlog](https://uk.mathworks.com/matlabcentral/fileexchange/57902-symlog)。 – Hoki