6
$\begingroup$

I'm looking for a straight forward way to highlight a single bar in a BarChart, i.e. a BarChart of country GDP where you highlight your country.

There's a great animation QA with a highlighted bar but I couldn't figure out how to simplify that down to a simple static barchart.

I think it should be via a ColorFunction rule with a user defined function but I'm not getting it, i.e.

data = Range[6]*2;
f[x_] := If[x == 1, Hue[0.5], Hue[0.2]]
BarChart[data,
 ColorFunction -> f,
 ChartLabels -> Characters["abcdef"]]

does something similar to what I want but I can't figure out how to change which bar gets highlighted (or why it's that one - for any other number but 1 I lose the highlighted bar).

I would have thought I could specify the ChartLabel for the data point but I haven't figured out that either.

$\endgroup$
1
  • $\begingroup$ almost - mostly a typo and need to have ColorFunctionScaling False: data = Range[6]*2; f[x_] := If[x == 6, Hue[0.5], Hue[0.2]] BarChart[data, ColorFunction -> f, ColorFunctionScaling -> False, ChartLabels -> Characters["abcdef"]] $\endgroup$
    – Joe
    Dec 27, 2017 at 22:06

6 Answers 6

9
$\begingroup$

There are several wrappers that you can use to wrap around data. Please read the Details and Options section of the docs. If I understand you correctly you want to choose to highlight one bar only. A colour function will do that but easier simply to use a wrapper for highlighting one bar.

One way would be to replace the datum that you want highlighted with a wrapper version:

BarChart[data /. 4 -> Style[4, Red]]
BarChart[data /. 4 -> Callout[4, "Hello World"]]

enter image description here

Alternatively modify the data directly, e.g:

data[[2]] = Style[data[[2]], Red];
data[[3]] = Callout[data[[3]], "hello world"];
$\endgroup$
2
  • $\begingroup$ Thanks, I hadn't seen the wrapper of changing the style of the data point and then having it become part of the chart. BTW your Callout function doesn't work for me (v11.0.1). $\endgroup$
    – Joe
    Dec 23, 2017 at 22:43
  • $\begingroup$ Callout is >= 11.1 $\endgroup$ Dec 23, 2017 at 23:02
4
$\begingroup$

This approach allows you pick the bar that is highlighted by its label.

Module[{n = 6, chr = "d", data, lbls, assoc},
  data = 2 Range[n];
  lbls = CharacterRange["a", FromCharacterCode[ToCharacterCode["a"] + n - 1]];
  assoc = AssociationThread[lbls, data];
  BarChart[data /. assoc[chr] -> Style[assoc[chr], Hue[.5]],
    ChartStyle -> Hue[.2], ChartLabels -> lbls]]

chart

$\endgroup$
3
$\begingroup$

As a not-so-straightforward-yet-fun alternative, you can use a custom ChartElementFunction. In the following example, bars to be highlighted are indicated by metadata.

ClearAll[highlightBar]
highlightBar[d_: 1, r_: 3] := Module[{t}, 
    If[#3 === {}, System`BarFunctionDump`BasicBar[##], 
     Dynamic[t = Clock[{0, 1, 0.05}, d, r]; 
      Dynamic[{EdgeForm[], CurrentValue["Color"], 
       If[#3 === {"up"}, Rectangle[Transpose[#][[1]], {1, t} Transpose[#][[2]]], 
    Rectangle[Dot[{1 - t, t}, {Mean /@ #, Transpose[#][[1]]}], 
     Dot[{1 - t, t}, {Mean /@ #, Transpose[#][[2]]}]]], 
   FaceForm[], EdgeForm[Black], Rectangle @@ Transpose@#}]]]] &;

Examples:

BarChart[{1, 2, Style[3, Red] -> "up", 4, Style[5, Green] -> foo}, 
 ChartElementFunction -> highlightBar[2, 10]]

enter image description here

BarChart[{1, 2, 3 -> blah, 4, 5 -> blah}, 
 ChartElementFunction -> growingBar[1, 10], ChartStyle -> 64]

enter image description here

$\endgroup$
2
$\begingroup$

How about

data = Range[6]*2;
f[x_] := ReplacePart[ConstantArray[Hue[0.2], Length@data], x -> Hue[0.5]]
BarChart[data, ChartStyle -> f[3], ChartLabels -> Characters["abcdef"]]

enter image description here

$\endgroup$
1
$\begingroup$

And finally via use of a ColorFunction. It was hard to figure out because ColorFunctionScaling defaults to True and doesn't work unless you use the full expression form of Function.

BarChart[data, ColorFunction -> Function[{x}, If[x == 3, Red, Gray]], 
 ColorFunctionScaling -> False]
$\endgroup$
0
$\begingroup$

This may be the ugliest way to do it but it is certainly straightforward - I'm just adding it here for completeness.

data = Range[6]*2;
p1 = BarChart[data, ColorFunction -> f, 
   ChartLabels -> Characters["abcdef"]];
data2 = {0, 0, data[[3]], 0, 0, 0};
p2 = BarChart[data2, ChartStyle -> Red];
Show[p1, p2]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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