# Plotting Error Bars on a Log Scale

I have a plot with ErrorListPlot

data = Sort@RandomReal[1, {10, 2}];
error = RandomReal[0.5, 10];
errorplot = ErrorListPlot[
Partition[Riffle[data, ErrorBar /@ error], 2],
Joined -> True]


However, I would like to have it with the y-axis on a log scale. I can use ListLogPlot to get the log scale but this doesn't plot the errorbars.

logplot = ListLogPlot[
data,
PlotRange -> All,
AxesOrigin -> {0, 0},
Joined -> True
]


I tried Show[logplot, errorplot, PlotRange->All] to see if it would plot with the scale and ticks from the logplot but that didn't work right:

I also tried to take the Ticks from the logplot: Show[errorplot, Ticks -> Ticks /. AbsoluteOptions@logplot] but that just gives an error.

I tried to manually take the log of the data and then grab the tick-marks but that didn't work right

data = Sort@RandomReal[{10, 100}, {10, 2}];
error = RandomReal[20, 10];
logdata = Transpose[{data[[All, 1]], Log[10, data[[All, 2]]]}];
errorup = Log[10, data[[All, 2]] + error] - logdata[[All, 2]];
errordown = Log[10, data[[All, 2]] - error] - logdata[[All, 2]];
logerror = Log[10, error];
logplot = ListLogPlot[
data,
Joined -> True,
AxesOrigin -> {0, 0}
]
errorlogplot = ErrorListPlot[
Partition[
Riffle[logdata, ErrorBar /@ Transpose[{errordown, errorup}]], 2],
Joined -> True,
AxesOrigin -> {0, 0}
]
errorlogplot2 = ErrorListPlot[
Partition[
Riffle[logdata, ErrorBar /@ Transpose[{errordown, errorup}]], 2],
Joined -> True,
AxesOrigin -> {0, 0},
Ticks -> (Ticks /. AbsoluteOptions@logplot)
]


Is there an easy way to do this?

On the log scale the error bars will appear asymmetrical.

-
Have you tried LevelScheme? It's CustomTicks package is a superior alternative to trying to set it up by hand. The edition I have installed isn't functioning correctly, otherwise I would have posted it as an answer. But, it is worth a look. – rcollyer Apr 4 '12 at 3:58
Do you realize that 2 of your error bars on 1st plot have negative y-values? I guess it is an accident of making up a random data set, yet we should be aware of these logs of negative values. – Vitaliy Kaurov Apr 4 '12 at 7:53
@Vitaliy Kaurov, I realized that after I played with my random data more. I was originally working with a real dataset but it was simpler to post a line to generate random data then upload and link to the real data, however, my random data was slightly broken as you noticed. – s0rce Apr 4 '12 at 19:30

I always use the package ErrorBarLogPlots. From the website:

ErrorBarLogPlots.m is a package which adds log-scale plotting functions similar to the standard ErrorListPlot provided in Mathematica 6. The added functions are ErrorListLogPlot, ErrorListLogLinearPlot, and ErrorListLogLogPlot."

-
 Strange...Once I write: Needs["ErrorBarLogPlots.m´"], I get the following error: Needs::cxt: Invalid context specified at position 1 in Needs[ErrorBarLogPlots.m\.b4]. A context must consist of valid symbol names separated by and ending with . >> ... Am I doing something wrong? – Anastasiia Anishchenko Nov 30 '12 at 13:35 @AnastasiiaAnishchenko Just write Needs["ErrorBarLogPlots"]. – Markus Roellig Nov 30 '12 at 17:58 this doesn't work either...does one have to install anything in addition? I get this message: Needs::nocont: Context ErrorBarLogPlots was not created when Needs was evaluated. >> – Anastasiia Anishchenko Dec 3 '12 at 14:21 @AnastasiiaAnishchenko Hmm, I don't get this error. Have you installed the package? Here is the [link]( library.wolfram.com/infocenter/MathSource/6747) . Download the zip file and install it, then retry the Needs command. – Markus Roellig Dec 4 '12 at 9:40

A one-liner solution (see a bit below lengthy explanation)

This is a bit hacky solution, yet its simplicity prompted me to post it. Load package and make up a data set:

Needs["ErrorBarPlots"]
data = Sort@RandomReal[1, {10, 2}]; error = RandomReal[0.2, 10];

errorplot = ErrorListPlot[Partition[Riffle[data, ErrorBar /@ error], 2],
Joined -> True, PlotRange -> All, Frame -> True, Axes -> False]


IMPORTANT: nothing goes below x-axis - not the data, not the error bars. Otherwise your log-scale will break - you cannot take log of negative numbers.

Now lets take a look at the "guts" of the produced graphics:

errorplot // InputForm


Line graphics primitive (sometimes with Offset) applied to sets of points given by coordinates like {x, y}. You just need to replace all these pairs by {x, Log@y}. Careful with Offset - its 1st argument needs to be left a lone. Luckily for us it has an integer 0 so it is easy to avoid applying a pattern that distinguishes it from real numbers we need to deal with.

So here is your one-liner solution:

lerrorplot = errorplot /. {x_Real, y_Real} -> {x, Log@y}


Notice undesirable non-standard ticks on vertical axes (corresponding to log values). To check that it is indeed correct - compare versus ListLogPlot:

check = ListLogPlot[data, Joined -> True, Frame -> True,
Axes -> False, PlotStyle -> {Thickness[.03], Orange, Opacity[.3]}];
Show[check, lerrorplot, PlotRange -> All]


A perfect match. Notice the ticks on vertical axes now are in traditional log-scale type (corresponding to original un-scaled data). Of course, your error bars got log-scaled too. Warning: be careful with these ReplaceAll type of solutions - you may be up to a surprise to what exactly is getting replaced. So always analyse your code to avoid unpleasant urprises.

-
 +1, for a straightforward solution. Looking at the code for ErrorListPlot, it uses ReplaceAll to effect its changes. Although it is a little more thorough and discriminating in it's approach. – rcollyer Apr 4 '12 at 13:31 Nice answer. BTW I liked the ripped-out look of your InputForm picture; Mathematica? It's ideal for pictures that have to convey the message "There's more of this, but that's not important". – Sjoerd C. de Vries Apr 4 '12 at 13:40 @SjoerdC.deVries I use the software is called Snagit. It'd be cool to implement it in Mathematica. – Vitaliy Kaurov Apr 4 '12 at 16:30 Thanks very much, I ended up using the ErrorBarLogPlot package linked by @Markus Roellig since in the end I need a log-log plot. I tried lerrorplot = errorplot /. {x_Real, y_Real} -> {Log@x, Log@y} but I just got a green box. – s0rce Apr 4 '12 at 19:25

## Without using the "ErrorBarPlots" Package

dataX = Sort@RandomReal[1, 10];
dataY = RandomReal[{0.5, 1}, 10];
error = RandomReal[0.5, 10];
errorH = dataY + error;
errorL = dataY - error;
f[y_] := Transpose[{dataX, y}];

ListLogPlot[{f[errorH], f[errorL], f[dataY]},
Filling -> {1 -> {2}},
Joined -> {False, False, True}]


Edit

Following @rcollyer's suggestion

dataX = Sort@RandomReal[1, 10];
dataY = RandomReal[{0.5, 1}, 10];
error = RandomReal[0.5, 10];
f[y_] := Transpose[{dataX, y}];

PlusMinus[a_, b_] := {a + b, a - b, a};

ePlot[plotFun_, dataX_, plusMinList_] :=
plotFun[{
f[plusMinList[[All, 1]]],
f[plusMinList[[All, 2]]],
f[plusMinList[[All, 3]]]},
Filling -> {1 -> {2}},
Joined -> {False, False, True}]
ePlot[ListLogPlot, dataX, plusMinList]

-
+1, awesome. Very straightforward. – rcollyer Apr 4 '12 at 14:56
@rcollyer Thanks! Filling is widely supported by almost all Plotting primitives. I use it always to draw error bars. – belisarius Apr 4 '12 at 14:59
This could easily be transformed into a function that accepts the form {_, PlusMinus[_,_} and plots it on the plotting function of your choice: ListPlot, ListLogPlot, etc. – rcollyer Apr 4 '12 at 15:05
@rcollyer Done :) – belisarius Apr 4 '12 at 15:57
Nice! If more traditional error bars are desirable, options can be added: ListLogPlot[..., PlotMarkers -> {"-", "-", "\[FilledCircle]"}]` – Vitaliy Kaurov Apr 4 '12 at 17:34