Log scale graphic with negative value
215 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Camil Hamel
il 22 Feb 2011
Risposto: Alexandre HYAFIL
il 13 Apr 2017
I want to plot a graphic with data that varies over many order (from 10e-4 to 10e-8) with some positive and negative values. Using 'semilog' or 'set xaxis log' can't plot my negative values (witch is normal). When I plot with a normal scale, we don't really see the variability of my datas, we only see the very high values and all the small one are not very visible because there are to close to zero. What would you suggest me to be able to show all my data (even the negative values) and be able to show the variability (like on a log-scale graph). Thank you
0 Commenti
Risposta accettata
Matt Tearle
il 24 Feb 2011
Oookay, I think I have it. If you're going to do this a lot, you may want to make yourself your own function. So, see if this does it for you:
function negsemilogx(x,y)
% Do log10 but keep sign
xlog = sign(x).*log10(abs(x));
% Just to get axis limits
plot(xlog,y,'o')
% Get limits
lims = xlim;
wdth = diff(lims);
% Wrap negative data around to positive side
xlog(xlog<0) = xlog(xlog<0) + wdth;
% Plot
plot(xlog,y,'o')
% Mess with ticks
tck = get(gca,'XTick')';
% Shift those that were wrapped from negative to positive (above) back
% to their original values
tck(tck>lims(2)) = tck(tck>lims(2)) - wdth;
% Convert to string, then remove any midpoint
tcklbl = num2str(tck);
tcklbl(tck==lims(2),:) = ' ';
% Update tick labels
set(gca,'XTickLabel',tcklbl)
Then to try it out:
>> x = -100:100;
>> y = x.^3;
>> negsemilogx(x,y)
3 Commenti
Più risposte (7)
Richard
il 22 Feb 2011
When you choose "log" as the scale for an axis, Matlab either chooses to use log10(x) or -log10(-x) as the transform, depending on whether your data is in the positive or negative domain. As you've found, you can't have both at the same time because both halves map data into the [-inf inf] space.
You can play with your own transforms by transforming the data yourself and at the same time manipulating the XTickLabel property of the axes so that you show untransformed data values. For example, this splices the normal negative and positive transforms, (with the singularity at 0 untransformed):
x = -100:100;
y = x.^3;
xt = x;
xt(xt>0) = log10(1+xt(xt>0));
xt(xt<0) = -log10(1-xt(xt<0));
figure;
ax = axes;
plot(xt,y);
set(ax, 'XTick', [-2 -1 0 1 2], ...
'XTickLabel', {'-100', '-10', '0', '10', '100'});
1 Commento
njj1
il 2 Giu 2016
Great answer. I didn't know about the transform (though it's quite obvious in hindsight). My problem has been dealing with small numbers in the log10 domain. In this case, if you simply try to transform the data using a sign(x)*log10(abs(x)), then there are problems, as the exponents are negative. Hence, the plot is pretty jacked because small negative numbers are changed into positive numbers and small positive numbers are changed into negative numbers. Anyways, thanks!
Matt Tearle
il 22 Feb 2011
Richard pretty much beat me to it. Here's a slightly more automated way to get the tick marks. However, unfortunately there's no TeX markup for tick labels, so you'll have to choose how you want them to appear -- plain exponent values (2, 3, 4, etc), values written out in full (100, 1000, etc), or some scientific notation (but without TeX markup, eg "10^3" or "1e3")
% Make some fake data
n = 1:20;
y = factorial(n);
y(2:2:end) = -y(2:2:end);
% Bad plot
plot(n,y,'o')
% Transform
ylog = sign(y).*log10(abs(y));
figure
plot(n,ylog,'o')
% Do nothing else to get just exponents. Otherwise:
yt = get(gca,'YTick')';
set(gca,'YTickLabel',num2str(sign(yt).*10.^abs(yt)))
% Or, for scientific notation
set(gca,'YTickLabel',strcat('10^',cellstr(num2str(abs(yt)))))
0 Commenti
Matt Tearle
il 22 Feb 2011
Dumb question, but is there any reason you can't just look at the absolute values? ( abs in MATLAB)
0 Commenti
Kilbock Lee
il 11 Nov 2013
I think my way is easier using logical operation true false.
Assuming the matrix is P(x,y),
LogP=((P > 0).*log10(P))+(-(P<0).*log10(-P))
and then, plot LogP
First term converts positive values into log scale and Second term does the negative values
0 Commenti
Alexandre HYAFIL
il 13 Apr 2017
Hi everyone,
I have just written a code that replots all the elements in your figure in negative/positive log-scale. It's for the Y axis but could be very simply adapted for the X axis: http://fr.mathworks.com/matlabcentral/fileexchange/62549-yscale-symlog
To use it: x = ... y = ... plot(x,y, ...); yscale_symlog;
Hope it will work for you!
0 Commenti
Vedere anche
Categorie
Scopri di più su 2-D and 3-D Plots in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!