# How to get proper Callout in BarChart?

Consider the following data.

data={{2419, 2918, 2887, 2980, 2981, 2410, 1689, 18}, {1630, 2829, 3096,
3252, 3137, 1350, 545, 2463}, {648, 1172, 1394, 1457, 1420, 772,
259, 11180}, {723, 1637, 1173, 1187, 1256, 418, 133, 11775}, {448,
611, 653, 629, 579, 124, 41, 15217}, {1556, 1767, 1884, 2106, 1904,
356, 26, 8703}, {19, 23, 35, 19, 23, 7, 1, 18175}};

legends={"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday", "\[LongDash]"};

weeks={"field 1", "field 2", "field 3", "field 4", "field 5", "field 6","field 7"};


Now plotting using,

colors=ColorData[97, "ColorList"];

BarChart[
Reverse[data],
ChartLayout->"Stacked",
ChartLegends->legends,
ChartLabels->{Reverse@weeks,None},
ChartStyle->(Directive[EdgeForm[White],#]&/@colors),
LabelingFunction->labelingFunction,
LabelStyle->Directive[FontFamily->"Source Sans Pro",FontSize->12],
PlotTheme->"Detailed",
ImageSize->Large,
AspectRatio->(1/3),
BarOrigin->Left,
FrameLabel->{None,"counts"}
]


If I use labelingFunction=(Placed[If[#1==0,"",#1],Center]&) then certain labels overlap or can hardly be seen. So instead I want to use precisely targeted Callout.

So I use

labelingFunction=(If[MatchQ[#2,Alternatives[{2,7}]],Callout[If[#1==0,"",#1],Automatic,Background->None],Placed[If[#1==0,"",#1],Center]]&)


where I precisely target the tiny bar's labels for example {2,7}. The problem is I can't reduce the gap between the data and the Callout's Leader even if I use LeaderSize->{Automatic,Automatic,0} option for Callout.

Moreover when I use the second labeling function the thickness of the bar is reduced automatically creating large gaps between bars. I don't want that.

Can someone help me? Thanks.

• I am using version 12 but when I try the code on version 11.3 the second labelingFunction seems to not even display the Placed labels. – user13892 May 12 '19 at 10:46
• Any solution please, even a hacky solution will do. – user13892 May 13 '19 at 12:35
• Or even some ideas I can try to get it working. – user13892 May 13 '19 at 21:11

I tried the following which seems to be working in this smaller example and also in the original example from the question. But the problem is this only works in version 11.3 not in 12.0. In 12.0, it gives pink graphics box.

data={{1,2,3},{2,4,6},{3,6,9}};

BarChart[
data,
ChartLayout->"Stacked",
BarOrigin->Left,
PlotTheme->"Detailed",
FrameTicks->All,
ImageSize->Large,
LabelingFunction->(Switch[#2,
{1,2|3},Callout[#1,
{Center,{0,0}}(*working in 11.3*),
(*{Above,Automatic}(*working in 12.0*),*)
],
_,Callout[#1,Center]
]&)
]


If you comment out the line

{Center,{0,0}}(*working in 11.3*),


and un-comment the line

(*{Above,Automatic}(*working in 12.0*),*)


then it atleast runs in version 12.0.

But the problem is in {[1],[2]} the [1] controls the position of the leader and [2] controls the position of the label. If I set [1] as Center then version 12.0 doesn't understand it. Also putting Automatic in [2] and Center in [1] is interpreted as a no leader Callout, i.e. basically same as Callout[...,Center] or Placed[...,Center]. Using Above in [1] works but it touch the top side of the bar but I want it in the center. Secondly, Automatic in [2] ignores any optional directives like Background->None which gives Callout's label with a background but I don't want that. Now can someone please look into it, atleast give me a hacky workaround this.

Also can someone please confirm whether this is a bug or a new implementation in 12.0. I can't believe WRI changed the function Callout even though it was not Experimental.

If it can't be solved I might have to downgrade my main system.

Also is there a way to connect the notebook front end to both kernels, 11.3 and 12.0 at the same time. So I can run certain commands in older version.

1. It would be nice to have a way to run certain cells in specified kernel.
2. Also a way to move all current definitions from one kernel to the other one instantly without evaluation the commands again one by one in the other kernel. (Basically copy the current state of one kernel and paste it on the other one)

Do you have an image in your mind how this plot should look like to be considered as good for your purpose?

The whole labeling problem, at least to some extend, is to create a graphics free of conflicts and pack as much information in as possible.

That said, with your code, this is what I have tried.

data = {{2419, 2918, 2887, 2980, 2981, 2410, 1689, 18}, {1630, 2829,
3096, 3252, 3137, 1350, 545, 2463}, {648, 1172, 1394, 1457, 1420,
772, 259, 11180}, {723, 1637, 1173, 1187, 1256, 418, 133,
11775}, {448, 611, 653, 629, 579, 124, 41, 15217}, {1556, 1767,
1884, 2106, 1904, 356, 26, 8703}, {19, 23, 35, 19, 23, 7, 1,
18175}};

legends = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
"Saturday", "Sunday", "\[LongDash]"};

weeks = {"field 1", "field 2", "field 3", "field 4", "field 5",
"field 6", "field 7"};

colors = ColorData[97, "ColorList"];

labelingFunction = (Callout[#1, If[#1 < 1000, Automatic, Center]] &);

BarChart[Take[Reverse[data], All], ChartLayout -> "Stacked",
ChartLegends -> legends, ChartLabels -> {Reverse@weeks, None},
ChartStyle -> (Directive[EdgeForm[White], #] & /@ colors),
LabelingFunction -> labelingFunction,
LabelStyle ->
Directive[FontFamily -> "Source Sans Pro", FontSize -> 12],
PlotTheme -> "Detailed",
ImageSize -> Large,
AspectRatio -> 1,
BarOrigin -> Left,
FrameLabel -> {None, "counts"},
BarSpacing -> {0, 1}
]


There seems to have some hiccups there for the leader lines.

And for 11.3, it doesn't have the problem.