我想绘制以下内容 - 见下文。
我想使用半学术的原因 - 或其他什么,也许你有建议? - 数据是如此之低,以至于所有正数据都显示为零。
当然,半决赛不适用于负面数据。但是我能做什么?目标是积极和消极数据在图中以某种方式显示为不同于零。
我看到了这个问题(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);
答案 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)
希望这能解决你的问题。