4
$\begingroup$

I am still using GeneralizedBarChart,although Mathematica documentation says:

As of Version 7.0, GeneralizedBarChart has been superseded by RectangleChart.

However, I could so far not figure out, how to conveniently get the same output, especially of the x-axis labelling, from RectangleChart or from any other Mathematica function.

GeneralizedBarChart is used by giving for each bar the position, height, and widths:

GeneralizedBarChart[{ {pos1,height1,widths1} ..} ]

For example:

Needs["BarCharts`"]

data={{-0.125, 1225, 0.15}, {0.025, 2007, 0.15}, {0.175, 1017, 
  0.15}, {0.325, 1508, 0.15}, {0.475, 2878, 0.15}, {0.625, 2785, 
  0.15}, {0.775, 2042, 0.15}, {0.925, 4257, 0.15}, {1.075, 651, 0.15}};

GeneralizedBarChart[data, Frame -> True, Axes -> False]

enter image description here

My question is: How do I get a similar output with a labeled x-axis using RectangleChart, BarChart or any other Mathematica function? The output of Mathematica's Histogram function would be also ok. But as far as I see Histogram needs as input the raw data and does not accept already binned data.

Thank you for your help.

Daniel

$\endgroup$
5
$\begingroup$

You can use RectangleChart with a custom ChartElementFunction that modifies the built-in chart element functions to re-center the rectangles based on the first column of input data.

ClearAll[cF]
cF[f_: "Rectangle", o : OptionsPattern[]] :=
 Module[{ori = Charting`ChartStyleInformation["BarOrigin"], box}, 
   box = Switch[ori, Top | Bottom, {#3[[1]] + {-1, 1}/2 Subtract @@ #[[1]], #[[2]]}, 
     Right | Left, {#[[1]], #3[[1]] + {-1, 1}/2 Subtract @@ #[[2]]}]; 
   ChartElementDataFunction[f, o][box, ##2]] &

You also need a function to transform your 3D data to a form that can be used with RectangleChart:

ClearAll[gbcToRc]
gbcToRc = Thread[#[[All, {3, 2}]] -> #[[All, 1]]] &;

or

gbcToRc  = {#3, #2} -> # & @@@#& (* thanks: Mr.Wizard *)

Examples:

data = {{-0.125, 1225, 0.15}, {0.025, 2007, 0.15}, {0.175, 1017,  0.15}, 
        {0.325, 1508, 0.15}, {0.475, 2878, 0.15}, {0.625, 2785,  0.15}, 
        {0.775, 2042, 0.15}, {0.925, 4257, 0.15}, {1.075, 651, 0.15}};

RectangleChart[gbcToRc @ data, 
 Frame -> True, Axes -> False, BarSpacing -> 0, ChartStyle -> 3, 
 ChartElementFunction -> cF[]]

Mathematica graphics

RectangleChart[gbcToRc @ data, 
 Frame -> True, Axes -> False, BarSpacing -> 0, ChartStyle -> 3, 
 ChartElementFunction -> cF["FadingRectangle", "GradientOrigin" -> Top]]

Mathematica graphics

RectangleChart[gbcToRc @ data, 
 Frame -> True, Axes -> False, BarSpacing -> 0, ChartStyle -> 3, BarOrigin -> Top, 
 ChartElementFunction -> cF["FadingRectangle", "GradientOrigin" -> Top]]

Mathematica graphics

RectangleChart[gbcToRc @ data, 
 Frame -> True, Axes -> False, BarSpacing -> 0, ChartStyle -> 3, BarOrigin -> Left, 
 ChartElementFunction -> cF["FadingRectangle", "GradientOrigin" -> Top]]

Mathematica graphics

RectangleChart[gbcToRc @ data, 
 Frame -> True, Axes -> False, BarSpacing -> 0, ChartStyle -> 3, BarOrigin -> Right, 
 ChartElementFunction -> cF["FadingRectangle", "GradientOrigin" -> Top]]

Mathematica graphics

$\endgroup$
  • $\begingroup$ This is a nice answer, which clearly shows that one has to do a lot of gymnastics to achieve with RectangleChart the same result as with GeneralizedBarChart. Thanks. $\endgroup$ – dnet Feb 28 '17 at 17:23
  • $\begingroup$ Great answer! {#3, #2} -> # & @@@ data also works, and though it may be a little less efficient that shouldn't matter here, especially since plotting functions have become rather slow. $\endgroup$ – Mr.Wizard Feb 28 '17 at 18:33
  • $\begingroup$ Thank you @Mr.Wizard. I updated with the alternative you suggested. $\endgroup$ – kglr Feb 28 '17 at 18:45
  • $\begingroup$ Can one in this aproach also show two overlapping histograms with two monochrom bar colors? Similar to my answer below using Histogram? RectangleChart[gbcToRc /@ {data, data2},ChartStyle -> {Red, Green},...]does not work. $\endgroup$ – dnet Mar 3 '17 at 8:56
  • $\begingroup$ @dnet, i will look into how to modify cF to handle multiple data sets. $\endgroup$ – kglr Mar 3 '17 at 9:25
3
$\begingroup$

It's relatively easy to put together a function to generate your own primitives from the data formatted as you already have it:

Clear[bchart]
bchart[data_, filling_: Blue, border_: Black] := Graphics[{
   EdgeForm[border], FaceForm[filling],
   Rectangle[{#1 - #3/2, 0}, {#1 + #3/2, #2}] & @@@ data},
  Frame -> True, AspectRatio -> 1/GoldenRatio
]

bchart[data]

Mathematica graphics

The colors default to blue filling with black borders, but you can indicate your own:

bchart[data, Darker@Green, Red]

Mathematica graphics

$\endgroup$
  • $\begingroup$ Thank you for your answer! However, with this approach one cannot use the many options that Histogram or RectangleChart offer out of the box. $\endgroup$ – dnet Feb 28 '17 at 17:27
1
$\begingroup$

I found now the following solution combining Histogram and WeightedData, which is good enough for the problem at hand, where all histogram bars are of identical width, not overlapping and without gaps.

plothisto[dat : {{_, _, _} ..}, opts : OptionsPattern[]] := plothisto[{dat}, opts];

plothisto[dat : {{{_, _, _}..} ..}, 
  opts : OptionsPattern[]] := Module[{xmin, xmax, dx},
  dx = dat[[1, 1, 3]];
  xmin = dat[[1, 1, 1]] - dx/2;
  xmax = dat[[1, -1, 1]] + dx/2;
  Histogram[
   MapThread[
    WeightedData, {dat[[All, All, 1]], dat[[All, All, 2]]}], {xmin, 
    xmax, dx}, FilterRules[{opts}, Options[Histogram]]]
  ]

For example:

data = {{-0.125, 1225, 0.15}, {0.025, 2007, 0.15}, {0.175, 1017, 
    0.15}, {0.325, 1508, 0.15}, {0.475, 2878, 0.15}, {0.625, 2785, 
    0.15}, {0.775, 2042, 0.15}, {0.925, 4257, 0.15}, {1.075, 651, 
    0.15}};
data2 = data;
data2[[All, 2]] = RandomReal[{0, 2000}, Length[data]];
plothisto[{data, data2}, ChartStyle -> Opacity[1], Frame -> True, 
 Axes -> False]

enter image description here

The advantage for me is that the graphical output of Histogram is close to my needs.

However, this is surely not a general replacement of GeneralizedBarChart!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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