5

Consider the following data:

data1={73.9377, 54.4122, 53.0826, 24.1936};
data2={76.828, 49.1673, 45.7883, 18.9015};

I defined my own BarChart as follows:

MyBarCharts[list_]:= 
 BarChart[
   list,
   Frame -> {{True, None}, {True, None}}
 ]

When applying MyBarCharts to data1 and data2 I get (not really surprising) two different (with regard to the coordinate system) plots. Now I would like to have for both plots the exact same coordinate system. I know that with Histogram it works as follows:

Histogram[
data2,
PlotRange -> Part[PlotRange /. Options[Histogram[
                                       data1,
                                       PlotRange -> Automatic
                                       ],PlotRange], 2],
Frame -> {{True, None}, {True, None}}]

But the implementation of that approach in MyBarCharts does not give the desired result. Has anyone an idea?

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
John
  • 4,361
  • 1
  • 26
  • 41

3 Answers3

4

I suggest redefining your MyBarCharts to take additional options as:

MyBarCharts[list_, options:OptionsPattern[]] := 
    BarChart[list, Frame -> {{True, None}, {True, None}}, options]

Then you can supply a plot range that's the same for both as:

MyBarCharts[data1, PlotRange -> {All, {0, 75}}]
MyBarCharts[data2, PlotRange -> {All, {0, 75}}]
rm -rf
  • 88,781
  • 21
  • 293
  • 472
  • 1
    I'd change options___ to options:OptionsPattern[] as it is clearer in intent. – rcollyer Mar 19 '12 at 15:05
  • I want Mathematica to define its own "global" plot range, as I have to plot hundreds of histograms. – John Mar 24 '12 at 17:10
  • It's relatively easy to work out what the PlotRange will be for bar charts. E.g. data = {{-2, -3}, {-5, -6}, {-7, -8}, {-9, -10}}; BarChart[data, PlotRange -> {{0, Length@Flatten@data + 1}, {Min@{data, 0}, Max@{data, 0}}}] – Chris Degnen Jun 10 '12 at 10:44
3

Extracting the PlotRange from a BarChart is not as straightforward as it should be. If no PlotRange is specified in creating the chart, then Options will return PlotRange -> All and AbsoluteOptions will return PlotRange -> {{0., 1.}, {0., 1.}

bc = BarChart[{1, 2, 3, 4}];

Options[bc, PlotRange]
(* {PlotRange -> All} *)

AbsoluteOptions[bc, PlotRange]
(* {PlotRange -> {{0., 1.}, {0., 1.}}} *)

The incorrect result from AbsoluteOptions appears to be related to the presence of dynamic objects in the graphics expression (i.e. the bars with their mouseover effects) . I don't know why this causes AbsoluteOptions to go wrong, but a workaround is to replace the dynamic bars with straighforward rectangles, allowing AbsoluteOptions to extract the correct PlotRange. Thus, a replacement for AbsoluteOptions for BarCharts is:

barChartOptions[chart_, opts___] := 
 AbsoluteOptions[chart /. 
  Tooltip[StatusArea[RawBoxes[DynamicBox[{_, RectangleBox[data__]}]], _], _] :> 
    Rectangle[data], opts]

barChartOptions[bc, PlotRange]
(* {PlotRange -> {{0.545455, 4.45455}, {0., 4.}}} *)
Simon Woods
  • 84,945
  • 8
  • 175
  • 324
1

Similar to R.M's answer I suggest that you implement a set of custom options for MyBarCharts. You can then use SetOptions to define defaults for your function, pass BarChart options to your function, etc. I described in some detail how to do this here:

Create a Function with Customized Options

See this question for the context of that answer.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371