Question

I have a vector, call it x, which contains very small numbers that I calculated from a mean. I'd like to plot the logarithmic transform of x, say y=10*log10(x), along with errorbars equal to +- 2 standard deviations calculated when finding the mean.

To do this, I'm using the following code:

figure
errorbar(lengths, 10*log10(x), ...
    10*log10(x-2*std_x), 10*log10(x+2*std_x), 'o')

My problem is that since x contains such small values, x-2*std_x is usually a negative number, and you can't take the log of negative numbers.

So I suppose my question is how can I plot errorbars in the logarithmic domain when subtracting the standard deviation in the linear domain gives me negative numbers? I can't do the +-

Was it helpful?

Solution

You can replace those values with a small value but log-able (say, 40 dB lower):

minb = x-2*std_x;
mask = (minb <= 0);
minb(mask) = x/1e4;
... use 10*log10(minb) instead

Or just threshold to some minimum:

K = min(x) / 1e4; % so that K is 40 db below the smallest x
... use 10*log10(max(K, x-2*std_x)) instead.

Or similar stuff.

EDIT to summarize comments and further thoughts:

One should probably think about why have error bars. Normally error bars tend to indicate some measure of confidence / probability (e.g. x% of the time, the value is between the indicated bounds). In this case, where some logarithm is taken of a quantity, it is likely that the quantity is drawn from a non-negative distribution. In that case, it is probably more correct to use bounds that are not mean +/- K * std_deviation to indicate bounds.

Assuming a unimodal distribution with cdf F(x), the "proper" bounds (i.e. smallest, for a given probability) would probably be such that

F'(x1) = F'(x2), F(x2) - F(x1) = desired_probability, and x1 <= mode <= x2.

This is mean +/- K std_deviation for a symmetric distribution, but as mentioned, a strictly positive distribution probably requires a different treatment.

OTHER TIPS

Actually you're calling errorbar wrong. You should call

figure
errorbar(lengths, 10*log10(x),10*log10(2*std_x), 'o')

If std_x is too small for this to work, you can write your own version of errorbar by plotting vertical lines from 10*log10(x-2*std_x) to 10*log10(x+2*std_x)

use errorbar in the two error configuration, then change the y-axis to be logarithmic:

eps = 1E-4;  %whatever you consider to be a very small fraction
ebl = min(2*std_x, x*(1-eps));
ebu = 2*std_x;
errorbar(lengths, x, ebl, ebu, 'o');
set(gca, 'YScale', 'log');

you may want to adjust your yaxis range manually using ylim

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top