1
$\begingroup$

Is there a way to draw a dotted line between the labels of a BarChart? In the following graph, I want to draw a line between for example "Rawlsian with \n corrected income taxes" and "Utilitarian (Progressive)". Since my actual chart have some other bars, instead of making labels' font small, I want to separate them with some lines among them. (They will not be visible on slides if I make them small)

 BarChart[{{10, 20, 30, 10}, {30, 20, 10, 4}, {4, 15, 40, 20}} ,
 ChartLabels -> {Placed[
    Rotate[#, 
       360 Degree] & /@ {"Rawlsian with \n corrected income taxes", 
      "Utilitarian (Progressive)", 
      " Utilitarian (Progressive) with \n corrected income taxes"}, 
    Before], None}, ChartLayout -> "Stacked", BarOrigin -> Left, 
 ImageSize -> Large]
$\endgroup$
  • $\begingroup$ Not exactly what you want: Framed[Rotate[#, 360 Degree], FrameStyle -> Dotted] & /@labels $\endgroup$ – Bob Hanlon Oct 13 '17 at 4:16
  • 3
    $\begingroup$ Rotating 360 Degree is the same as not rotating. Shorten to Framed[#, FrameStyle -> Dotted] & /@labels $\endgroup$ – Bob Hanlon Oct 13 '17 at 4:26
2
$\begingroup$

I would do it by inserting two empty bar charts, each labelled with a string of periods. Like so:

BarChart[
  {{10, 20, 30, 10}, {}, {30, 20, 10, 4}, {}, {4, 15, 40, 20}},
  ChartLabels ->
    {Placed[
      {"Rawlsian with \n corrected income taxes",
       Style["........................... ", 16],
       "Utilitarian (Progressive)",
       Style["........................... ", 16], 
       "Utilitarian (Progressive) with \n corrected income taxes"},
      Before],
    None},
  ChartLayout -> "Stacked",
  BarOrigin -> Left,
  ImageSize -> Large]

bar_chart

Update — Aligning the dotted lines

cdots = Style[StringJoin[ConstantArray["\[CenterDot]", 27]] <> " ", 18]
BarChart[
  {{10, 20, 30, 10}, {}, {30, 20, 10, 4}, {}, {4, 15, 40, 20}},
  ChartLabels ->
    {Placed[
       {"Rawlsian with \n corrected income taxes", cdots,
        "Utilitarian (Progressive)", cdots, 
        "Utilitarian (Progressive) with \n corrected income taxes"},
       Before],
     None},
  ChartLayout -> "Stacked", BarOrigin -> Left, ImageSize -> Large]

aligned

$\endgroup$
  • $\begingroup$ the dotted lines are not aligned with the ticks properly $\endgroup$ – M.R. Oct 14 '17 at 5:07
  • 1
    $\begingroup$ @M.R. Why should they be? They are not intended to relate to the ticks -- they are only intended as separators for the labels. If it really bothers you, you can replace . with \[CenterDot] $\endgroup$ – m_goldberg Oct 14 '17 at 6:20
  • $\begingroup$ @Hossein. Those marks aren't ticks; they are data group indicators. They are intended to help the viewer associate the label with data group that it labels. I do not know how to eliminate them. I do know how to align the dots to their group indicator. Perhaps it will make the chart look better to you that way. M.R. already complained about it, so I guess the lack of alignment is really more bothersome than I thought. I have made an update showing how do the alignment. $\endgroup$ – m_goldberg Oct 15 '17 at 0:06
1
$\begingroup$

Given m_goldberg's clever trick that provides a simple and effective solution, the following is definitely an overkill ... but added flexibility may be useful.

A covenient way to inject stuff into charts is to use a custom ChartElementFunction. The function ceF below injects desired lines in the middle of group spacings using coordinate information (accessible to chart element functions) and BarSpacing information passed as metadata.

We modify the input data associating with the first element of a data group a number that represents the offset from the left-bottom coordinate of the associated rectangle. Making this metadata depend on the BarSpacing option value we center the line in the spacing between data groups. The arguments control the starting point, the length and the style of the line.

ClearAll[ceF]
ceF[start_: 2, offset_: 120, style_: Directive[Black, Thick , Dashed]] := 
 Module[{}, {ChartElementDataFunction["Rectangle"][##], 
  style, If[#3 === {}, {}, Line[{{-start, -#3[[1]]/2 + #[[2, 1]]}, 
       Offset[{-offset, 0}, {-start, -#3[[1]]/2 + #[[2, 1]]}]}]]}] &

Examples:

options = {ChartLabels -> {Placed[{"Rawlsian with \n corrected income taxes", 
   "Utilitarian (Progressive)", 
    " Utilitarian (Progressive) with \n corrected income taxes"}, Before], None}, 
  ChartLayout -> "Stacked", BarOrigin -> Left, ImageSize -> Large};

With default arguments for ceF:

BarChart[{{10, 20, 30, 10}, {30 -> .2, 20, 10, 4}, {4 -> .2, 15, 40, 
   20}}, options, BarSpacing -> {0, .2}, ChartElementFunction -> ceF[]]

enter image description here

BarChart[{{10 -> .1, 20, 30, 10}, {30 -> .6, 20, 10, 4}, {4 -> .6, 15, 40, 20}}, 
 options, BarSpacing -> {0, .6}, 
 ChartElementFunction -> ceF[-2, 150, Directive[Thickness[.005], DotDashed, Red]]]

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.