# How to plot BarChart with error bars on logarithmic scale in Mathematica 9?

I'm quite new in Mathematica, and I would like to ask you to consider the next case:

I need to plot bar chart with error bars on logarithmic scale. From Wolfram site I took the function which allows to plot error bars on a bar chart with normal (non-log) scaling.

Thus, my ugly actual code looks like:

errorBar[type_: "Rectangle"][{{x0_, x1_}, {y0_, y1_}}, value_, meta_] :=
Block[{error},
error = Flatten[meta];
error = If[error === {}, 0, Last[error]];
{ ChartElementData[type][{{x0, x1}, {y0, y1}}, value, meta],
{Black, Line[{{{(x0 + x1)/2, y1 - error}, {(x0 + x1)/2, y1 + error}},
{{1/4 (3 x0 + x1), y1 + error}, {1/4 (x0 + 3 x1), y1 + error}},
{{1/4 (3 x0 + x1), y1 - error}, {1/4 (x0 + 3 x1), y1 - error}}}]}
}
]

figdata = {{4.01 -> 0.76, 1.73 -> 0.14, 3.95 -> 0.35},
{68.53 -> 16.32, 77.77 -> 11.13, 81.39 -> 27.32}};
xlables = {"r1", "r2"};
leftframename = "Frequency";

BarChart[ figdata, ChartElementFunction -> errorBar["Rectangle"],
ChartStyle -> {White, Gray, Black}, ChartLabels -> {xlables, None},
FrameLabel -> {None, Style[leftframename, 15, FontFamily -> "OpenSans"]},
FrameTicks -> {{{0, 10, 100, 1000}, None}, {None, None}},
Frame -> Left, BarSpacing -> {0, 0.5},
BaseStyle -> {FontWeight -> "Bold", FontSize -> 15},
ScalingFunctions -> "Log"]


And this produce the following graph: which is not what I really would like to receive.

The problems, that I don't know how to solve:

1. How to plot error bars in a proper way on log scale in BarChart?
2. How to make FrameTicks visible and on the same distance between each other?

Could anyone help me to put this together into working decision?

Unfortunately, the errors require recalculation in the scale of the logarithmically transformed axis, viz $y_i\pm\epsilon_i \mapsto\ln(e^{y_i}\pm\epsilon_i)$

Perhaps not the most elegant modification but for illustration:

errorBar[type_: "Rectangle"][{{x0_, x1_}, {y0_, y1_}}, value_,
meta_] := Block[{error}, error = meta;
error = If[error === {}, 0, First@error];
{ChartElementData[type][{{x0, x1}, {y0, y1}}, value, meta], {Red,
Line[{{{(x0 + x1)/2, Log[E^y1 - error]}, {(x0 + x1)/2,
Log[E^y1 + error]}}, {{1/4 (3 x0 + x1),
Log[E^y1 + error]}, {1/4 (x0 + 3 x1),
Log[E^y1 + error]}}, {{1/4 (3 x0 + x1),
Log[E^y1 - error]}, {1/4 (x0 + 3 x1), Log[E^y1 - error]}}}]}}]

figdata = {{4.01 -> 0.76, 1.73 -> 0.14,
3.95 -> 0.35}, {68.53 -> 16.32, 77.77 -> 11.13, 81.39 -> 27.32}};
xlables = {"r1", "r2"};
leftframename = "Frequency";

BarChart[figdata, ChartElementFunction -> errorBar["Rectangle"],
ChartStyle -> {White, Gray, Black}, ChartLabels -> {xlables, None},
Frame -> Left,
FrameLabel -> {None,
Style[leftframename, 15, FontFamily -> "OpenSans"]},
FrameTicks -> {{{Thread[{Range[0, 2], {1, 10, 100}}]}, None}, {None,
None}}, BarSpacing -> {0, 0.5},
BaseStyle -> {FontWeight -> "Bold", FontSize -> 15},
ScalingFunctions -> "Log"
]


You can test by making Line expression a Tooltip with the label the value E^y1 + error etc. EDIT

For the second question, using PlotRangePadding helps:

BarChart[figdata, ChartElementFunction -> errorBar["Rectangle"],
ChartStyle -> {White, Gray, Black},
ChartLabels -> {Placed[xlables, Below], None}, Frame -> Left,
FrameLabel -> {None,
Style[leftframename, 15, FontFamily -> "OpenSans"]},
FrameTicks -> {{{Thread[{Range[0, 3], {1, 10, 100, 1000}}]},
None}, {None, None}}, BarSpacing -> {0, 0.5},
BaseStyle -> {FontWeight -> "Bold", FontSize -> 15},
ScalingFunctions -> "Log"] • Thank you very much! It solved the problem. However, could it be possible to make ticks up to 1000? I have a number of graphs, and would like to use the same scale to show the difference between them. Simple changing in FrameTicks -> {{{Thread[{Range[0, 2], {1, 10, 100}}]}, None} to FrameTicks -> {{{Thread[{Range[0, 3], {1, 10, 100, 1000}}]}, None} doesnt help too much. – Manul Nov 6 '13 at 21:00

The following is alternative implementation of the function errorBar. It takes a scaling function as an optional argument and it inherits the color of the bar to style the errorbar:

ClearAll[errorBar2];
errorBar2[sf_: Identity, type_: "Rectangle"][{{x0_, x1_}, {y0_, y1_}}, value_, meta_] :=
Block[{error, isf = InverseFunction[sf][y1]}, error = Flatten[meta];
error = If[error == {}, {0, 0}, {sf[isf - #], sf[isf + #]} &@error];
{ChartElementData[type][{{x0, x1}, {y0, y1}}, value, meta],
{Thick, Dynamic@Darker@CurrentValue["Color"],
Line[{{{(x0 + x1)/2, error[[1, 1]]}, {(x0 + x1)/2, error[[2, 1]]}},
{{1/4 (3 x0 + x1), error[[2, 1]]}, {1/4 (x0 + 3 x1), error[[2, 1]]}},
{{1/4 (3 x0 + x1), error[[1, 1]]}, {1/4 (x0 + 3 x1), error[[1, 1]]}}}]}}]


Example:

figdata = {{4.01 -> 0.76, 1.73 -> 0.14, 3.95 -> 0.35},
{68.53 -> 16.32, 77.77 -> 11.13, 81.39 -> 27.32}};
xlables = {"r1", "r2"};
leftframename = "Frequency";
opts = {ChartLabels -> {xlables, None}, Frame -> Left,
BarSpacing -> {0, 0.5}, ChartStyle -> "DarkRainbow",
FrameLabel -> {None, Style[leftframename, 15, FontFamily -> "OpenSans"]},
FrameTicks -> {{{Thread[{Range[0, 2], {1, 10, 100}}]}, None}, {None, None}},
BaseStyle -> {FontWeight -> "Bold", FontSize -> 15}, ImageSize -> 400};

Row[BarChart[figdata, Sequence @@ opts, ScalingFunctions -> #,
PlotLabel -> (Style[ScalingFunctions -> #, 16]),
ChartElementFunction -> errorBar2[ToExpression[# /. None->"Identity"], "GlassRectangle"]] & /@
{None, "Log"}, Spacer] 