Single RegionPlot with different mesh functions
One possibility is to draw the mesh in a second plot and draw it over the original one:
Show[
RegionPlot[
{a, regions}, {p, 0, 10}, {q, 0, 10},
FrameLabel -> {p, q},
MaxRecursion -> 3,
PlotLegends ->
SwatchLegend[Automatic, Prepend[b, "Infeasible: " And @@ a],
LegendMarkerSize -> {20, 20}]
],
RegionPlot[
a, {p, 0, 10}, {q, 0, 10},
MeshFunctions -> {#1 + #2 &, #1 &},
Mesh -> {Range[0, 20, 1]},
MeshStyle -> {Orange, Green}]
]
The code above also demonstrates how to achieve size independent mesh spacing. The only thing to watch out for is that you might need to adjust the bounds of the Range
to cover the values returned by your mesh functions.
Update: It turns out we can use a simple modifications of the option setting in OP for MeshFunctions
to get the desired result:
1. Boole:
RegionPlot[{a, regions}, {p, 0, 10}, {q, 0, 10},
FrameLabel -> {p, q}, MaxRecursion -> 3,
MeshFunctions -> {Boole[# + #2 >= 15] (#1 + #2) &, Boole[# + #2 >= 15] #1 &},
Mesh -> {30, 20},
MeshStyle -> {Orange, Green},
PlotLegends -> SwatchLegend[Automatic, Prepend[b, "Infeasible: " And @@ a],
LegendMarkerSize -> {20, 20}]]
Alternatively, specify a list of values for each mesh function using, for example, Mesh -> {Range[15, 30, .5], Range[0, 10, .25]}
to get
2. Piecewise:
We can also use
MeshFunctions -> {Piecewise[{{#1 + #2, # + #2 >= 15}}] &,
Piecewise[{{#1, # + #2 >= 15}}] &}
to get the same result.
3. ConditionalExpression:
Finally, we can use ConditionalExpression
if we use list of values for the Mesh
option setting (and increase PlotPoints
to remove artifacts):
RegionPlot[{a, regions}, {p, 0, 10}, {q, 0, 10},
FrameLabel -> {p, q}, MaxRecursion -> 3,
MeshFunctions -> {ConditionalExpression[#1 + #2, # + #2 >= 15] &,
ConditionalExpression[#1, # + #2 >= 15] &},
Mesh -> {Range[0, 20, .5], Range[0, 10, .5]},
PlotPoints -> 100,
MeshStyle -> {Orange, Green},
PlotLegends -> SwatchLegend[Automatic, Prepend[b, "Infeasible: " And @@ a],
LegendMarkerSize -> {20, 20}]]
Original answer:
An alternative approach: Use Texture[img]
as the PlotStyle
setting for the desired regions using img
of your choice:
colors = ColorData[97] /@ Range[4];
texture1 = Texture[ExampleData[{"TestImage", "Mandrill"}]];
legendmarker1 = Graphics[{texture1, Polygon[{{0, 0}, {1, 0}, {1, 1}, {0, 1}},
VertexTextureCoordinates -> Automatic]}];
RegionPlot[{a, regions}, {p, 0, 10}, {q, 0, 10}, FrameLabel -> {p, q},
MaxRecursion -> 3, PlotStyle -> Prepend[colors, texture1],
TextureCoordinateFunction -> (Rescale[{#, #2}, {0, 10}/2] &),
TextureCoordinateScaling -> False,
PlotLegends -> SwatchLegend[Prepend[colors, texture1],
Prepend[b, Row[{"Infeasible: ", And @@ a}]],
LegendMarkers -> Prepend[ConstantArray[Automatic, Length@b], legendmarker1],
LegendMarkerSize -> {30, 30}]]
To use a hatched image instead of "Mandrill"
, you can use a simplified version of the function hatchingF
from this answer
ClearAll[hatchedTexture]
hatchedTexture[ps_: None, cols_: {Red, Orange}, m_: {10, 10},
t_: AbsoluteThickness[5]] :=
RegionPlot[True, {x, 0, 1}, {y, 0, 1},
MeshFunctions -> {# + #2 &, # &}, Mesh -> m, MeshShading -> None,
MeshStyle -> (Directive[t, #] & /@ cols), Frame -> False,
PlotRangePadding -> 0, PlotStyle -> ps, BaseStyle -> EdgeForm[],
BoundaryStyle -> None]
Replace texture1
and legendmarker1
above with
texture2 = Texture[Rasterize @ hatchedTexture[]];
legendmarker2 = Graphics[{texture2, Polygon[coords = {{0, 0}, {1, 0}, {1, 1}, {0, 1}},
VertexTextureCoordinates -> (coords/2)]}];
to get
Use texture2 = Texture[Rasterize @ hatchedTexture[LightBlue]]
to get
Use texture2 = Texture[Rasterize @ hatchedTexture[texture1, {Black, Black}]]
if you wish to be cruel and put "Mandrill"
behind bars: