5
$\begingroup$

This is my code:

BarChart[{{0.25, 0.4, 0.15}, {0.172, 0.25, 0.18}, {0.101, 0.26, 
   0.17}},
 BarSpacing -> {0.15, 1}, PlotTheme -> "Business", 
 ChartLegends -> {Text[Style["BXE", 12]],
   Text[Style["CXE", 12]],
   Text[Style["TQ", 12]]},
 ChartStyle -> "GrayTones", LabelingFunction -> Above, 
 ChartLabels -> {{"Large", "Small", "Overall"}, None}, 
 BaseStyle -> Directive[FontSize -> 11], 
 PlotLabel -> 
  Style["Volume", FontSize -> 15]]

I have to change only the first bar and I want it is like the bar in picture.

enter image description here

$\endgroup$
  • $\begingroup$ You need to play with ChartElementFunction. $\endgroup$ – Kuba Jan 27 '17 at 9:03
  • 2
    $\begingroup$ I should say that this looks awfully like the "chartjunk" Tufte is railing against. Is styling the bar in this way absolutely necessary? $\endgroup$ – J. M. will be back soon Jan 27 '17 at 9:07
  • $\begingroup$ But I don't know how can I change only one bar and where I have to insert ChartElementFunction. I'm sorry, as you can see, I'm not an expert. @Kuba $\endgroup$ – Andrea Jan 27 '17 at 9:09
  • $\begingroup$ @ J. M.♦ Almost necessary, I need to differentiate the first bar from the others, but I can't do it with another color, do you have any suggestion? $\endgroup$ – Andrea Jan 27 '17 at 9:17
  • $\begingroup$ If you only need to distinguish one, make it white (outlined) or black, and the rest the opposite color. $\endgroup$ – J. M. will be back soon Jan 27 '17 at 9:23
2
$\begingroup$

This highlights the first bar. You still need ChartStyle for the legend to be correct.

data = {{0.25, 0.4, 0.15}, {0.172, 0.25, 0.18}, {0.101, 0.26, 0.17}};

Set the three GrayLevels here:

levels = GrayLevel /@ {0.9, 0.5, 0.1};

Change the Edgeform to change the appearance of only the first bar.

styles = {{{EdgeForm[{Thick, Black, Dashing[0.05]}], levels[[1]]}, 
    levels[[2]], levels[[3]]}, levels, levels};

Plot:

BarChart[MapThread[Style, {data, styles}, 2], BarSpacing -> {0.15, 1},
  PlotTheme -> "Business", 
 ChartLegends -> {Text[Style["BXE", 12]], Text[Style["CXE", 12]], 
   Text[Style["TQ", 12]]}, ChartStyle -> levels, 
 LabelingFunction -> Above, 
 ChartLabels -> {{"Large", "Small", "Overall"}, None}, 
 BaseStyle -> Directive[FontSize -> 11], 
 PlotLabel -> Style["Volume", FontSize -> 15]]

enter image description here

$\endgroup$
4
$\begingroup$

enter image description here

To create hatched rectangle primitives we can use the function hatchF (from this answer and this answer to closely related questions).

ClearAll[hatchF]
hatchF[mf_List: {# &, #2 &}, mesh_List: {50, 50}, style_: GrayLevel[.5], 
 opts : OptionsPattern[]] := ParametricPlot[{x, y}, {x, 0, 1}, {y, 0, 1}, Mesh -> mesh, 
  MeshFunctions -> mf, MeshStyle -> style, BoundaryStyle -> None, 
  opts, Frame -> False, PlotRangePadding -> 0, ImagePadding -> 0, Axes -> False]

Use hatchF to create two Graphics objects

t1 = hatchF[{# - #2 &}, {30}, White, MeshShading -> {GrayLevel[.8], GrayLevel[.5]}];
t2 = hatchF[{# - #2 &, #2 + # &}, {30}, Directive[Thick, White], 
   MeshShading -> {{GrayLevel[.6], GrayLevel[.8]}}];

and take an image from ExampleData[]

t3 = ExampleData[{"ColorTexture", "Metal4"}];

We can use Texture[t1], Texture[t2], etc. as directives for styling individual data elements using Style[element1, Texture[t1]], Style[element2, Texture[t2]] etc. Together with the built-in (but undocumented) function System`BarFunctionDump`TextureBar used as the setting for ChartElementFunction we get the desired styles for selected data elements.

BarChart[{{Style[0.25, Texture@ t1], 0.4, 0.15}, 
  {0.172, Style[0.25, Texture@t3], Style[0.18, Texture@t2]}, {0.101, .26,    0.17}},
 BarSpacing -> {0.15,  1},
 ChartLegends -> {Text[Style["BXE", 12]], Text[Style["CXE", 12]], 
   Text[Style["TQ", 12]]}, ChartStyle -> "GrayTones", 
 LabelingFunction -> Above, 
 ChartLabels -> {{"Large", "Small", "Overall"}, None}, 
 BaseStyle -> Directive[FontSize -> 11], 
 PlotLabel -> Style["Volume", FontSize -> 15], 
 ChartElementFunction -> System`BarFunctionDump`TextureBar]

gives the picture above.

$\endgroup$
3
$\begingroup$

The question might be considered a duplicate of this question, but for clarity I will show how by adapting the answer given there.

barHatched[gap_, h_, seg_][{{xmin_, xmax_}, {ymin_, ymax_}}, ___] := 
 Module[{width, line, yt, yb, lend}, {yb, yt} = Sort[{ymin, ymax}];
  width = xmax - xmin;
  line = Table[{{xmin, i}, {xmax, i + width}}, {i, yb, yt - width, 
     h/seg}];
  lend = line[[-1, 1, 2]];
  line = {
    Line[line], 
    Line[Table[{{xmin + i, yb}, {xmax, yb + width - i}}, {i, h/seg, 
       width, h/seg}]], 
    Line[Table[{{xmin, lend + i}, {xmax - (lend + width - yt) - i, 
        yt}}, {i, h/seg, width + h/seg, h/seg}]]
    };
  {{Opacity[.2], EdgeForm[], 
    Rectangle[{xmin, ymin}, {xmax + gap, ymax}]},
   {CapForm["Butt"], line}, {FaceForm[], 
    Rectangle[{xmin, ymin}, {xmax, ymax}]}}
  ]

barSolid[{{xmin_, xmax_}, {ymin_, ymax_}}, ___] := Rectangle[{xmin, ymin}, {xmax, ymax}]

mixedBar[args : {{xmin_, xmax_}, {ymin_, ymax_}}, ___] := 
 If[xmax < 3, barHatched[0, 5, 35][args], barSolid[args]]

BarChart[
 Transpose[{
   {2, -1, 1.5, -3, 3, 2.5},
   {2, -1, 1.5, -3, 3, 2.5}
   }],
 ChartElementFunction -> {
   mixedBar,
   barSolid
   }
 ]

Mathematica graphics

The idea is to build custom CharElementFunctions for the bar appearances. To have variation with a set we need to make a ChartElementFunction which depends on the position of the bar. This is what the mixedBar function is for.

$\endgroup$
  • $\begingroup$ The proposed duplicate has a static CharElementFunction, what's more, the docs don't show how to do such a dynamic one either. This is a really nice answer. $\endgroup$ – Feyre Jan 27 '17 at 21:19
  • $\begingroup$ @Feyre You're right. I retracted my vote, so it's up to others now to decide whether it should be considered a duplicate or not. $\endgroup$ – C. E. Jan 27 '17 at 21:33

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.