# Hatch Fill in ListDensityPlot

I would like to make the black colour hatched/striped instead of a solid fill, so that when I overlay it on top of another plot, I can still see the colours underneath. I know how to change the opacity of the black, but that doesn't help to see the colours underneath. Does anyone have any ideas?

data1 = {{0.004, 0.00004, 1}, {0.004, 0.00005, 0}, {0.004,
0.00006000000000000001, 0}, {0.005, 0.00004, 2}, {0.005,
0.00005, 1}, {0.005, 0.00006000000000000001, 1}, {0.006,
0.00004, 5}, {0.006, 0.00005, 5}, {0.006,
0.00006000000000000001, 1}};
data2 = {{0.004, 0.00004, 0}, {0.004, 0.00005, 0}, {0.004,
0.00006000000000000001, 0}, {0.005, 0.00004, 1}, {0.005,
0.00005, 0}, {0.005, 0.00006000000000000001, 0}, {0.006,
0.00004, 1}, {0.006, 0.00005, 1}, {0.006,
0.00006000000000000001, 0}};
plot1 = ListDensityPlot[data1, ColorFunctionScaling -> None,
InterpolationOrder -> 0,
ColorFunction ->
Function[structure,
Which[structure == 0, White, structure == 1, Blue, structure == 2,
Green, structure == 3, Yellow, structure == 4, Red,
structure == 5, Purple, structure == 6, Gray, True, Black]]]
plot2 = ListDensityPlot[data2, ColorFunctionScaling -> None,
InterpolationOrder -> 0,
ColorFunction ->
Function[structure,
Which[structure == 0, Opacity[1, Black], structure == 1,
Opacity[0, White]]]]
Show[plot1, plot2]


Any help would be much appreciated :-)

EDIT:

This has now been solved for small data sets. For large data sets, however, it does not seem to work. For example, consider these two larger data sets:

If I now try to follow the proposed solution:

Get["PathToFile/data1BIG.dat"];
Get["PathToFile/data2BIG.dat"];
plot1 = ListDensityPlot[data1BIG, ColorFunctionScaling -> None,
InterpolationOrder -> 0,
ColorFunction ->
Function[structure,
Which[structure == 0, White, structure == 1, Blue, structure == 2,
Green, structure == 3, Yellow, structure == 4, Red,
structure == 5, Purple, structure == 6, Gray, True, Black]]]
plot2 = ListDensityPlot[data2BIG, ColorFunctionScaling -> None,
InterpolationOrder -> 0,
ColorFunction ->
Function[structure,
Which[structure == 0, Opacity[1, Black], structure == 1,
Opacity[0, White]]]]
Show[plot1, plot2]
plot3 = Normal[plot2] /.
Polygon[x_, VertexColors -> {Opacity[0, _] ..}] :> Nothing /.
Polygon[x_, ___] :> Polygon[x];
region = RegionUnion @@ Cases[plot3, _Polygon, Infinity];
rp = RegionPlot[region, Mesh -> {40}, MeshFunctions -> {# - 100 #2 &},
MeshShading -> {Opacity[1, Gray], None}, BoundaryStyle -> None];
Show[plot1, rp, ImageSize -> 500]


This causes errors at the RegionPlot stage, the first of which is "Boolean region cannot be automatically discretized". I appreciate all the help everyone has put in so far, and if anyone knows how to make this scalable to large data sets, then it will truly come in useful. Many thanks!

• A dot fill would also be fine. Just any type of fill that would allow me to see the colours underneath. Thank you – Bart Sep 2 '18 at 14:15
• This is the closest example that I have found: mathematica.stackexchange.com/questions/98187/… But I am still stuck with it... – Bart Sep 2 '18 at 14:35
• And this gives some more examples: mathematica.stackexchange.com/questions/64159/… I cannot figure out how to apply this to my situation. – Bart Sep 2 '18 at 14:55
• Why not use Opacity[0.5, Black]? – Alex Trounev Sep 2 '18 at 18:04
• @AlexTrounev That is a sensible suggestion and was indeed the closest I could get to what I wanted initially. However, the problem with using opacity is that, since it is a solid fill, it mixes with the colours underneath to make new colours. This makes the plot very difficult, if not impossible, to read. e.g. White + Opacity[0.5, Black] = gray, Blue + Opacity[0.5, Black] = dark blue, etc. So if I also had, let's say, 'gray' and 'dark blue' as original colours in my plot1, then you can see where the confusion would arise... – Bart Sep 3 '18 at 11:22

1. Post-process plot2 to remove all the white polygons and VertexColors from the remaining polygons:
plot3 = Normal[plot2] /. Polygon[x_, VertexColors -> {Opacity[0, _] ..}] :> Nothing /.
Polygon[x_, ___] :> Polygon[x] ;

1. Extract polygons from plot3 and use RegionUnion to get a region:
region = RegionUnion @@ Cases[plot3, _Polygon, Infinity];

1. Use region in RegionPlot with desired Mesh* option settings:
rp = RegionPlot[region, Mesh -> {40}, MeshFunctions -> {# - 100 #2 &},
MeshShading -> {Opacity[1, Gray], None}, BoundaryStyle -> None];

1. Show the RegionPlot output with plot1:
Show[plot1, rp, ImageSize -> 500]


Use

Mesh -> {20, 15},
MeshFunctions -> {# + 100 #2 &, # - 100 #2 &},
MeshShading -> {{Opacity[.5, Black], None}, {None, Opacity[.5, Black]}}


to get

• Thank you very much for your helpful solution. I have upvoted and marked it as correct since you exactly answered the question which I had asked. Unfortunately, this solution does not work on the larger data set which I actually want to use it on :-( (so much for giving minimum working examples...) When trying this with a 50x50 grid, the RegionPlot step fails because "boolean region cannot be automatically discretized", among other errors. I will edit my question with further details in the hopes that anybody has time. Thank you again for the quick and detailed response :-) – Bart Sep 3 '18 at 15:46
• @Bart, Thank you for the accept. I will post an update if i find solution for the larger data sets. – kglr Sep 3 '18 at 18:09
• Thank you, it is much appreciated! – Bart Sep 4 '18 at 7:45