5
$\begingroup$

I have a plot that includes a RegionPlot. I want to make a rectangle with the same shading as in the region plot to show as a legend. The dumb way I can think off is to make another region plot over a small rectangular space and show that as a legend, but that does not seem like a great idea considering I might want to change the plots.

Any better suggestions?

For practice, I want to label the following example:

RegionPlot[x^2 + y^3 < 2, {x, -2, 2}, {y, -2, 2}, 
  MeshFunctions -> {(2 #1 - #2) &, (2 #1 - #2) &}, Mesh -> 100]

Keywords: hatched filling, legend with hatched filling

$\endgroup$
10
$\begingroup$

Perhaps a "quick" appoach (in addition to looking at hyperlink of @rm-rf):

msp[f_, {xmin_, xmax_}, {ymin_, ymax_}, mfun_, mnum_, swatchsize_, 
  opts : OptionsPattern[]] := Module[{pm, swl},
  pm = RegionPlot[x < 1, {x, 0, 1}, {y, 0, 1}, MeshFunctions -> mfun, 
    Mesh -> IntegerPart@(mnum/(swatchsize/10)), Frame -> False, 
    PlotRange -> {{0, 1}, {0, 1}}, 
    Evaluate@FilterRules[{opts}, Options[RegionPlot]], 
    ImageSize -> swatchsize];
  swl = SwatchLegend["Expressions", LegendMarkers -> pm, 
    LegendMarkerSize -> swatchsize];
  RegionPlot[f, {x, xmin, xmax}, {y, ymin, ymax}, 
   MeshFunctions -> mfun, Mesh -> mnum, 
   Evaluate@FilterRules[{opts}, Options[RegionPlot]], 
   PlotLegends -> swl]]

Some examples:

msp[x^2 + y^3 < 2, {-2, 2}, {-2, 2}, {#1 &, #2 &}, 50, 50]

enter image description here

msp[x^2 + y^3 < 2, {-2, 2}, {-2, 2}, {#1 + #2 &, #1 - #2 &}, 50, 50]

enter image description here

msp[x^2 + y^3 < 2, {-2, 2}, {-2, 2}, {#1 &, #2 &}, 50, 50, 
 PlotStyle -> Yellow, BoundaryStyle -> {Thick, Purple}]

enter image description here

UPDATE

mspmod[f_, {xmin_, xmax_}, {ymin_, ymax_}, mfun_, mnum_, swatchsize_, 
  col_, opts : OptionsPattern[]] := 
 Module[{pm, swl}, 
  pm = RegionPlot[x < 1, {x, 0, 1}, {y, 0, 1}, MeshFunctions -> mfun, 
      Mesh -> IntegerPart@(mnum/(swatchsize/10)), Frame -> False, 
      PlotRange -> {{0, 1}, {0, 1}}, PlotStyle -> #, 
      Evaluate@FilterRules[{opts}, Options[RegionPlot]], 
      ImageSize -> swatchsize] & /@ col;
  swl = SwatchLegend["Expressions", LegendMarkers -> pm, 
    LegendMarkerSize -> swatchsize];
  RegionPlot[f, {x, xmin, xmax}, {y, ymin, ymax}, 
   MeshFunctions -> mfun, Mesh -> mnum, PlotStyle -> col, 
   Evaluate@FilterRules[{opts}, Options[RegionPlot]], 
   PlotLegends -> swl]]

Example:

mspmod[{x^3 - y^2 > 2, x^2 + y^3 > 3, 
  x^3 - y^2 > 2 && x^2 + y^3 > 3}, {-3, 3}, {-3, 3}, 50, 50, {Red, 
  Green, Yellow}]

enter image description here

$\endgroup$
  • $\begingroup$ I tried to make improvements to make this valid for two functions, but the coloring of the legend is always just one of them. Any suggestions on how to make msp accept multiple functions? Worst case, I'll just use Show. Thanks! $\endgroup$ – Lina Feb 16 '14 at 1:07
  • $\begingroup$ @Lina , I suspect Show is simplest way. Will think about when I get time. Hyperlink already referred in other comments may give inspiration. $\endgroup$ – ubpdqn Feb 16 '14 at 3:27
  • $\begingroup$ @Lina see update $\endgroup$ – ubpdqn Feb 16 '14 at 7:56
  • 1
    $\begingroup$ @Lina for some reason the update I made disappeared so I reupdated. $\endgroup$ – ubpdqn Feb 19 '14 at 12:13
3
$\begingroup$

You can also create hatched images (say, img) using ParametricPlot and use them with PlotStyle -> Texture[img] in RegionPlot:

Reusing the function hatchF from this answer:

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]

t1a = hatchF[{# - #2 &}, {60}, Red, PlotStyle -> Opacity[.5, Yellow]];
t1b = hatchF[{# + #2 &}, {60}, Purple, PlotStyle -> Opacity[.5, Cyan]];
t2a = hatchF[{# + #2 &}, {80}, None, MeshShading -> {None, Blue}];
t2b = hatchF[{# - #2 &}, {80}, None, MeshShading -> {Red, None}];
t3 = ExampleData[{"TestImage", "Lena"}];
t4 = ImageCrop[ExampleData[{"ColorTexture", "Metal4"}], {600, 600}];
Grid[Transpose@Partition[{t1a, t1b, t2a, t2b, t3, t4}, 2]]

enter image description here

funcs = {Abs[x^3 - y^2] > 2, x^2 + y^3 < 1/2};
labels = Append[TraditionalForm /@ #, TraditionalForm[And @@ #]] & @ funcs;
markers = Append[ImageCrop[#, 30] & /@ {t1a, t1b}, ImageCrop[Show[t1a, t1b], 30]];
legend = Grid[Transpose[{markers, labels}], Alignment -> Left];

Legended[#, legend] &@
 RegionPlot[funcs, {x, -2, 2}, {y, -2, 2}, 
  PlotStyle -> {{Opacity[.5], Texture @ t1a}, {Opacity[.5], Texture @ t1b}}]

enter image description here

In version 11, use

  PlotStyle -> {Texture @ SetAlphaChannel[t1a, .5], Texture @ SetAlphaChannel[t1b, .5]}

Use t2a and t2b in places of t1a and t1b to get:

enter image description here

Use t3 in place of t2 and

 markers = Append[ImageCrop[#, 30] & /@ {t2a, ImageResize[t3, {50, 50}]}, 
   ImageCrop[Show[SetAlphaChannel[ImageResize[t3, {50, 50}], .9], 
     SetAlphaChannel[t2a, .3]], 30]];

to get

enter image description here

Replace t3 with t4 to get

enter image description here

$\endgroup$

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.