Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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:

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?

share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

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.

enter image description here

EDIT

For the second question, using PlotRangePadding helps:

BarChart[figdata, ChartElementFunction -> errorBar["Rectangle"], 
 ChartStyle -> {White, Gray, Black}, 
 ChartLabels -> {Placed[xlables, Below], None}, Frame -> Left, 
 PlotRangePadding -> {0, {0, 3}}, 
 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"]

enter image description here

share|improve this answer
    
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.