4
$\begingroup$

I'm trying to do a BarChart[] of some data and I'd like to add an additional XX axis below the chart with some additional information. This may also be done with an additional plot, as long as it does the job.

So my question is: how can I align the second plot to the XX axis, not to the plot itself?

In the example below I want from a to the end of gto include the labeling "first", from h to k to have "second", etc.

data = Transpose@{CharacterRange["a", "t"], 
    Table[RandomInteger[{1, 20}], {20}]};
padding = {{7, 7}, {10, 7}};
plot1 = BarChart[
   data[[All, 2]],
   ChartLabels -> data[[All, 1]]
   ];
plot2 = Plot["", {x, 1, 20}, Axes -> {True, False}, 
   AxesOrigin -> {0, 0}, 
   Ticks -> {{{0, ""}, {3.5, "first", {0, 0}}, {7, ""}, {8.5, 
       "second", {0, 0}}, {10, ""}, {13, "third", {0, 0}}, {16, 
       ""}, {18, "fourth", {0, 0}}, {20, ""}}, None}
   ];
GraphicsColumn[{plot1, plot2}]
(*out:*)

enter image description here

I have found some other questions and answers regarding plot/graphic alignment, but none regarding the alignment to the axis itself. I'd appreciate all help!

Thanks

$\endgroup$
6
$\begingroup$

Why not simply

data = Table[RandomInteger[{1, 20}], {20}];

Define the partition

par = {{1, 8}, {9, 13}, {14, 16}, {17, 20}};

Plot

BarChart[
 Take[data, #] & /@ par,
   ChartLabels -> {{"1st", "2d", "3rd", "4th"}, CharacterRange["a", "t"]}]

enter image description here

Update

bar =
 BarChart[
  data,
  ChartLabels -> CharacterRange["a", "t"]];

lip =
 ListPlot[
  ConstantArray[20, 20],
  AxesOrigin -> {1, -3},
  Frame -> True,
  FrameStyle -> {{Black, Opacity@0}, {Black, Opacity@0}},
  FrameTicks -> {{Range[0, 20, 5], None}, {{{1, "a"}, {4, "first", 0}, {7, "g"}, {9.5, "2nd", 0}, {12, "l"}, {14, "n"}, {20, "t"}}, None}},
  PlotStyle -> Opacity@0]

enter image description here

Show[{lip, bar}, PlotRange -> All]

enter image description here

$\endgroup$
  • $\begingroup$ I had also thought about that. However, I'd prefer to really have a bar under as it would give more emphasis to the bar. I may also want to change the bar itself to add some more information, so I'd like to avoid having the labels presented like that $\endgroup$ – Sosi Nov 10 '15 at 17:19
2
$\begingroup$

For a quick and dirty method you could make use of RectangleChart as your second where the width of each rectangle is equal to the number of items in the top groups. Grouping your data in the BarChart will assist with visualising this.

bc = BarChart[Partition[data[[All, 2]], 5],
  ChartLabels -> {IntegerName[Range[4]], CharacterRange["a", "t"]}];
rc = RectangleChart[{{4, 5}, {4, 2}, {4, 3}, {4, 6}}, 
  ChartLabels -> IntegerName[Range[4]]];
GraphicsColumn[{bc, rc}]

enter image description here

You will have to tweak the PlotRangePadding to get them to line up just so. You can use the ColorFunction option to keep the colour the same on each bar.

There is a better way were you can grab the bounds of the rectangles of the bars in the BarChart and use them in the RectangleChart for the width of the rectangles. See this post for details on how to use the ChartElementFunction option to get these. What are Epilog x-Axis Positions In BoxWhiskerChart

Hope this helps.

$\endgroup$
  • $\begingroup$ Now that I'm thinking about your answer and @eldo's above, there may be a way to combine them more easily. Maybe duplicate the top plot, use the labeling such that only the groups ("first", "second"...) and not the bars ("a", "b"...) are labeled and then group them as you are suggesting with the padding. This has the advantage of yielding more approximate sizes than creating another chart altogether. $\endgroup$ – Sosi Nov 10 '15 at 17:38
2
$\begingroup$

Another way, using Frame (you need to shift your endpoints by 0.5 to match the bars)

data = Transpose@{CharacterRange["a", "t"], 
    Table[RandomInteger[{1, 20}], {20}]};
plot1 = BarChart[data[[All, 2]], ChartLabels -> data[[All, 1]]];
plot2 = Plot["", {x, 1, 20}, Frame -> {{False, False}, {True, False}},
   Axes -> False, 
   FrameTicks -> {{{0.5, ""}, {4, "first", {0, 0}}, {7.5, ""}, {9, 
       "second", {0, 0}}, {10.5, ""}, {13.5, "third", {0, 0}}, {16.5, 
       ""}, {18.5, "fourth", {0, 0}}, {20.5, ""}}, None}];
Show[plot2, plot1, PlotRange -> All, PlotRangePadding -> 2]

enter image description here

$\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.