TransWikia.com

Can I Center Chart Elements in BarChart

Mathematica Asked by Aaron Eiben on December 19, 2020

I am generating a bar chart in which each count is to be represented by a disk (or something similar). This alone seems straightforward: simply set the option ChartElements -> Graphics@Disk[]. But alas, it’s not perfect, as shown by the following example:

BarChart[#, ChartElements -> Graphics@Disk[], 
   ChartLabels -> {"bin " /@ #}, FrameLabel -> {"Bins", "Counts"}, 
   LabelStyle -> Directive[Black, Larger], PlotTheme -> "Detailed", 
   ImageSize -> Large] &@Range[8]

enter image description here

The first column should contain one whole disk. The second column should contain two whole disks, so on and so forth. This can be corrected by setting ChartElements -> {Graphics@Disk[], {1, 1}}, which produces

enter image description here

But notice how each column of disks is now off-center from its frame tick and label. This becomes far more evident as the number of counts increases; for example, when the charted values are squared:

enter image description here

I tried re-centering the labels under the columns of disks by changing ChartLabels -> Placed["bin " /@ #, {{0.39, 0}, {1, 1.5}}], which produced the following result:

enter image description here

The labels are now smaller and apparently invisible to FrameLabel, which overlaps them! I suppose that may be corrected by wrapping another Placed around the horizontal frame label, but all of this fine-tuning could be avoided in the first place if I can just get the disks to remain centered within thier columns.

So, is there a way to do that?

(Wrapping Placed around the disks themselves didn’t work…)

Thanks!

One Answer

We can post-process the BarChart output and modify the Inset arguments:

ClearAll[centerBars]
centerBars = # /. Graphics[GeometricTransformation[Inset[i_, a__], t_], o___, 
        PlotRange -> {{0, x1_}, yr_}, o2___] :> 
      Graphics[GeometricTransformation[Inset[i, {x1/2, 0}, {Center, Bottom}, {1, 1}], t],
        o, PlotRange -> {{0, x1}, yr}, o2] /. 
    Inset[i_, {x_, 0.}, a_, b_, c_] :> 
        Inset[i, {Ceiling[x], 0.}, {Center, Bottom}, b, c] &;

Examples:

charts = BarChart[(Range@8)^#, 
     ChartElements -> {Graphics[Disk[]], {1, 1}}, 
     ChartLabels -> {"bin " /@ (Range[8]^#)}, 
     FrameLabel -> {"Bins", "Counts"}, 
     LabelStyle -> Directive[Black, Larger], PlotTheme -> "Detailed", 
     PerformanceGoal -> "Speed", ImageSize -> 500] & /@ {1, 2};

Grid[Transpose[{charts, centerBars /@ charts}]]

enter image description here

Correct answer by kglr on December 19, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP