5

I am making a stacked bar chart which represents the concentration of a battery in different metals. I would like to make the metals differentiatable by adding a bit of texture to the rectangle in which they are represented. However, I can't make the chart's legend follow automatically the texture I have applied. Would you please know how to solve this? Here's my code (taken from this answer):

Defining the hatch function:

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]

Defining the textures:

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

Making the chart:

BarChart[
{Style[5, Texture@t1], Style[5, Texture@t2]},
ChartLayout -> "Stacked",
ChartLegends -> {Automatic, {"A", "B"}},
ChartElementFunction -> System`BarFunctionDump`TextureBar
]

Current output:

enter image description here

kglr
  • 394,356
  • 18
  • 477
  • 896
Tommy95
  • 97
  • 6

1 Answers1

8

Update: In versions 12.1+ you can use the new directive PatternFilling

 BarChart[{5, 5},
  ChartLayout -> "Stacked",
  ChartLegends ->  SwatchLegend[{PatternFilling[{"Checkerboard", Black, LightGray}, 
     ImageScaled[1]], 
    PatternFilling[{"DiamondBox", LightGray, Black},  ImageScaled[1]]},  {"A", "B"},
   LegendMarkerSize -> 30],
   ChartStyle -> {PatternFilling[{"Checkerboard", Black , LightGray}, 
      ImageScaled[1/20]], 
     PatternFilling[{"DiamondBox", LightGray, Black}, ImageScaled[1/20]]}

]

enter image description here

Original answer:

You can create thumbnails of the texture images with appropriate parameters and use them in ChartLegends:

thumbnails = ImageCrop[#, 50] & /@ {t1, t2};
legends = Grid[Transpose[{ImageResize[#, 20]& /@ thumbnails, {"A", "B"}}]];
BarChart[{Style[5, Texture @ t1], Style[5, Texture @ t2]}, 
  ChartLayout -> "Stacked", 
  ChartLegends -> legends, 
  ChartElementFunction -> System`BarFunctionDump`TextureBar]

enter image description here

Alternatively, define legends as

legends = SwatchLegend[ {"A", "B"}, LegendMarkerSize -> {20, 20}, 
 LegendMarkers -> thumbnails];

to get

enter image description here

kglr
  • 394,356
  • 18
  • 477
  • 896