How to make an exclusion plot in Mathematica, e.g. draw a filled area on one side of the contour line
Update 2: In version 12.1 you can use the directives PatternFilling
or HatchFilling
for MeshShading
:
ParametricPlot[
Evaluate[v f[x] + (1 - v) shiftF[f][x, .2, ar prr]], {x, 0, 1}, {v, 0, 1},
MeshFunctions -> { #4 &},
MeshShading -> {None, HatchFilling[]},
Mesh -> { {{1,Directive[Thick, Opacity[1],Red]},{0, White}}},
AspectRatio -> ar, ImageSize -> 400, Evaluate @ opts]
With MeshShading -> {None, PatternFilling["Diamond", ImageScaled[1/50]]}
we get
Update: a function to produce parallel-looking shifts:
ClearAll[shiftF, f]
shiftF [f_] := f[#] + {{0, #2}, {-#2/#3, 0}}.Normalize[f'[t] /. t -> #] &;
where the second argument controls the amount of "shift" and the third argument can be used to adjust for distortions caused by aspect ratio and plot range.
Examples:
cp = ContourPlot[Cos[x] + Cos[y], {x, 0, 3}, {y, 2.5, 9},
Contours -> {.5}, ContourStyle -> Directive[Blue, Thick],
ContourShading -> {None, None}, PlotRange -> {{0, 3}, {3, 9}}];
f = BSplineFunction[Cases[Normal@cp, Line[x_] :> x, ∞][[1]], SplineClosed -> False];
opts = Sequence[Frame -> True, Axes -> False, PerformanceGoal -> "Quality",
BoundaryStyle -> None, PlotRangePadding -> .1, PlotStyle -> None];
prr = Divide @@ First @ Differences @ PlotRange @ cp;
ar = 1;
ParametricPlot[Evaluate[v f[x] + (1 - v) shiftF[f][x, .2, ar prr]],
{x, 0, 1}, {v, 0, 1}, MeshFunctions -> {# + .5 #2 &, # - .5 #2 &, #4 &},
MeshStyle -> {GrayLevel[.5], GrayLevel[.5], Directive[Thick, Red]}, MeshShading -> None,
Mesh -> {80, 80, {1}}, AspectRatio -> ar, ImageSize -> 400, Evaluate@opts]
Change the shift parameter to -.2
to get
With ar = 6/4
and .2
as the second argument in shiftF[f]
we get
and with ar = 1/2
and .1
as the second argument in shiftF[f]
we get
cp2 = ContourPlot[{Cos[x] + Cos[y] == .5, (x - 2)^2 + ((y - 5)/2)^2 == 1},
{x, 0, 3}, {y, 2.5, 9},
ContourStyle -> {Directive[Blue, Thick], Directive[Red, Thick]},
ContourShading -> None, PlotRange -> {{0, 3}, {3, 9}}];
pnts = Cases[Normal@cp2, Line[x_] :> x, Infinity];
{fa1, fb1} = BSplineFunction[#, SplineClosed -> False] & /@ pnts;
cols = {Red, Green}; mfs = {# + .5 #2 &, #2 &}; mns = {80, 60};
i = 1;
Show[(j = i++; color = cols[[j]]; mf = mfs[[j]]; mn = mns[[j]];
ParametricPlot[#, {x, 0, 1}, {v, 0, 1}, Axes -> False, MeshFunctions -> {mf, #4 &},
MeshStyle -> {Directive[Opacity[.5, color], Thin], Directive[Thick, color]},
MeshShading -> None, Mesh -> {mn, {1}}, Evaluate@ opts]) & /@
{v fa1[x] + (1 - v) shiftF[fa1][x, .2, 1/2],
v fb1[x] + (1 - v) shiftF[fb1][x, .2, 1/2]}, PlotRange -> All]
fa = { Sin[4 #], Sin[3 #]} &;
ar = 5/4;
opts = Sequence[Frame -> True, PerformanceGoal -> "Quality",
BoundaryStyle -> None, PlotStyle -> None, Axes -> False,
PlotPoints -> 50, ImageSize -> 400, PlotRangePadding -> .2,
AspectRatio -> ar, PlotRange -> All];
ParametricPlot[Evaluate[v fa[u] + (1 - v) shiftF[fa][u, .1, ar]],
{u, 0, 2 Pi}, {v, 0, 1},
MeshFunctions -> {# - .5 #2 &, # + .5 #2 &, #4 &},
MeshStyle -> {GrayLevel[.5], GrayLevel[.5], Directive[Thick, Red]},
MeshShading -> None, Mesh -> {70, 70, {1}}, Evaluate@opts]
With ar = 1/2
we get
Related:
- Length of a curve parallel to a spline
- How can I offset a curve from the given data points?
- Make an offset curve (parallel curve)
Original answer:
You can use RegionFunction
to specify the shaded region and MeshFunctions
to create hatched shading:
ContourPlot[Cos[x] + Cos[y], {x, 0, 3}, {y, 2.5, 9}, Contours -> {.5},
ContourStyle -> Directive[Blue, Thick],
ContourShading -> {None, None}, PlotRange -> {{0, 3}, {3, 9}},
PlotPoints -> 100, Mesh -> 50, MeshFunctions -> { #1&, #2 &},
MeshStyle -> Directive[Thin, Gray],
RegionFunction -> (.2 <= Cos[#] + Cos[#2] <= .501 &)]
Alternatively, you can use RegionPlot
with MeshFunctions
to produce hatched or cross-hatched regions and use it as Prolog
in ContourPlot
:
ContourPlot[Cos[x] + Cos[y], {x, 0, 3}, {y, 2.5, 9}, Contours -> {.5},
ContourStyle -> Directive[Black, Thick], ContourShading -> None,
PlotRange -> {{0, 3}, {3, 9}},
Prolog -> RegionPlot[.2 <= Cos[x] + Cos[y] <= .5, {x, 0, 4}, {y, 2.5, 10},
Mesh -> 60, BoundaryStyle -> None,
MeshFunctions -> {5 #1 - #2 &, 5 #1 + #2 &},
MeshStyle -> Directive[Thin, Gray], PlotStyle -> None,
PlotPoints -> 100, PlotRange -> {{0, 3}, {0, 10}}][[1]]]
You get the same picture using ContourPlot[...][[1]]
as Epilog
in RegionPlot
RegionPlot[.2 <= Cos[x] + Cos[y] <= .5, {x, 0, 4}, {y, 2.5, 10},
Mesh -> 60, BoundaryStyle -> None,
MeshFunctions -> {5 #1 - #2 &, 5 #1 + #2 &},
MeshStyle -> Directive[Thin, Gray], PlotStyle -> None,
PlotPoints -> 100, PlotRange -> {{0, 3}, {3, 9}},
Epilog -> ContourPlot[Cos[x] + Cos[y], {x, 0, 3}, {y, 2.5, 9},
Contours -> {.5}, ContourStyle -> Directive[Black, Thick],
ContourShading -> None][[1]]]
Variations:
ContourPlot[{Cos[x] + Cos[y] == .5, Sin[x] Sin[y/2] == .5}, {x, 0, 3}, {y, 2.5, 9},
ContourStyle -> {Directive[Blue, Thick], Directive[Red, Thick]},
ContourShading -> None, PlotRange -> {{0, 3}, {3, 9}},
Epilog -> {RegionPlot[.2 <= Cos[x] + Cos[y] <= .5, {x, 0, 4}, {y, 2.5, 10},
Mesh -> 80, BoundaryStyle -> None,
MeshFunctions -> {5 #1 - #2 &, 5 #1 + #2 &},
MeshStyle -> Directive[Thin, Blue], PlotStyle -> None,
PlotPoints -> 100, PlotRange -> {{0, 3}, {0, 10}}][[1]],
RegionPlot[.2 <= Sin[x] Sin[y/2] <= .5, {x, 0, 4}, {y, 2.5, 10},
Mesh -> 100, BoundaryStyle -> None,
MeshFunctions -> {5 #1 - #2 &, 5 #1 + #2 &},
MeshStyle -> Directive[Thin, Pink], PlotStyle -> None,
PlotPoints -> 100, PlotRange -> {{0, 3}, {0, 10}}][[1]]}]
Use MeshFunctions -> {5 #1 - #2 &}
in the first RegionPlot
and MeshFunctions -> {5 #1 + #2 &}
in the second to get
Finally, rather surprising shading patterns with random MeshFunctions
:
ContourPlot[{Cos[x] + Cos[y] == .5, Sin[x] Sin[y/2] == .5}, {x, 0, 3}, {y, 2.5, 9},
ContourStyle -> {Directive[Blue, Thick], Directive[Red, Thick]},
ContourShading -> None, PlotRange -> {{0, 3}, {3, 9}},
Prolog -> (RegionPlot[.2 <= #[[1]] <= .5, {u, 0, 4}, {v, 2.5, 10},
Mesh -> #[[2]], BoundaryStyle -> None,
MeshShading -> {Directive[Opacity[.3], Hue[RandomReal[]]], White},
MeshFunctions -> {RandomInteger[{-1, 1}] #1 + RandomInteger[{-1, 1}] #2 &},
MeshStyle -> Directive[Thin, Gray], PlotStyle -> None, PlotPoints -> 50,
PlotRange -> {{0, 3}, {0, 10}}][[1]] & /@
{{Cos[u] + Cos[v], 10}, {Sin[u] Sin[v/2], 10}})]
You may specify additional Contours
and related ContourStyle
and ContourShading
.
ContourPlot[Cos[x] + Cos[y], {x, 0, 2.3}, {y, 2.5, 9},
Contours -> {.5, 0.4},
ContourStyle -> {None, Black},
ContourShading -> {None, LightBlue}]
Hope this helps.