# Dashed line with alternating colored dashes

I am doing a plot where I have multiple shaded regions, and I want the line that separates the two regions to be dashed with dashes being alternating colors (so the demarcation stands out from both regions).

For example, say I am plotting the two regions shown here

Plot[{1, Abs[BesselJ[1, x]]}, {x, 0, 20}, Filling -> Axis] The only way I could think to add the dashing was using ColorFunction, but it doesn't give what I'm looking for:

bgplot = Plot[{1, Abs[BesselJ[1, x]]}, {x, 0, 20},
Filling -> Axis, PlotStyle -> {Automatic, None}];
dashplot = Plot[Abs[BesselJ[1, x]], {x, 0, 20},
PlotStyle -> Thickness[.01],
ColorFunction -> (If[EvenQ[Floor[#]], Black, White]&),
ColorFunctionScaling -> False, PlotPoints -> 500];
Show[bgplot, dashplot] This is almost what I want, but the dashes are all the same length in the x-coordinate, whereas I'd prefer they be the same total length. Also, I have to have PlotPoints set to an unreasonably high value to avoid any gray regions.

Any ideas how to do this better?

A simple but flexible approach might be to plot the function twice, as in this example, with a solid color the first time overlaid by a dashed line the second:

f[x_] := Abs[BesselJ[1, x]];
Plot[{f[x], f[x]}, {x, -10, 10},
PlotStyle -> {Directive[Thick, White],
Directive[Thick, Dashing[{0.1, 0.1}]]}, Background -> LightGray] • Filling is optional... Nov 22, 2012 at 0:14
• Thanks a bunch! The plot above is now written Plot[{1, Abs[BesselJ[1, x]], Abs[BesselJ[1, x]]}, {x, 0, 20}, Filling -> {1 -> {2}, {2 -> Axis}}, PlotStyle -> {Automatic, {Thickness[.01], Black}, {Dashing[.05], White, Thickness[.01]}}]
– user4368
Nov 22, 2012 at 0:27

Here's one possibility (incorporating Mike's enhancements):

Plot[Abs[BesselJ[1, x]], {x, 0, 20},
Filling -> {1 -> Axis, 1 -> Top},
FillingStyle -> {Opacity[1/5, ColorData[1, 1]], Opacity[1/5, ColorData[1, 2]]},
Mesh -> Full, MeshFunctions -> {#1 &}, MeshShading -> {Red, Blue}, MeshStyle -> None,
PlotRange -> {0, 1}, PlotStyle -> Directive[AbsoluteThickness]] Alternatively:

Plot[Abs[BesselJ[1, x]], {x, 0, 20},
Filling -> {1 -> Axis, 1 -> Top},
FillingStyle -> {Opacity[1/5, ColorData[1, 1]], Opacity[1/5, ColorData[1, 2]]},
Mesh -> 90, MeshFunctions -> {Norm[{#1, #2}] &},
MeshShading -> {Red, Blue}, MeshStyle -> None,
PlotRange -> {0, 1}, PlotStyle -> Directive[AbsoluteThickness]] • That is nice, but it suffers from the same problem as my own solution. That is, each dash has the same size along the x coordinate only. Notice that the first two dashes are much longer than the fourth and fifth.
– user4368
Nov 22, 2012 at 0:14
• Is the second version more suitable, @Jason? Nov 22, 2012 at 0:19
• I was unaware of how to use Mesh, and I'm still pretty ignorant about it. I'm not quite sure what it's doing in this example. Using {#1&} as the mesh function, gives mesh points equally spaced along the x-coordinate. But {Norm[{#1, #2}] &} gives mesh based on the distance from the origin, which is better but not quite what I want. Notice there are still uneven sizes for the dashes. Mesh is definitely less clunky than the ColorFunction option I used.
– user4368
Nov 22, 2012 at 0:27
• Oh well, gave it a college try at least... Nov 22, 2012 at 0:33

Here's a way to use the "ArcLength" setting to get equal-length segments. One has to scale the coordinates so the arc length in the coordinate geometry is proportional to the arc length in the screen geometry. This can be done with ScalingFunctions, if the PlotRange is known; otherwise, the plot range will need to be computed and the plot redrawn.

Plot[Abs[BesselJ[1, x]],
{x, 0, 20},
Filling -> {1 -> Axis, 1 -> Top},
FillingStyle -> {Opacity[1/5, ColorData[1, 1]], Opacity[1/5, ColorData[1, 2]]},
PlotRange -> {0, 1}, PlotStyle -> Thickness[.01],
Mesh -> 18, MeshStyle -> None, MeshShading -> {Black, White},
MeshFunctions -> {"ArcLength"},
ScalingFunctions ->
{{GoldenRatio #/20 &, 20 #/GoldenRatio &},  (* scale by plot range & aspect ratios *)
None}
] Here's a two-pass function that computes the plot range and aspect ratio and inserts the appropriate scaling functions:

ClearAll[arclengthmesh];
SetAttributes[arclengthmesh, HoldAll];
arclengthmesh[plot_] := Module[{p, pr, ar},
p = plot;
pr = Ratios[Differences /@ PlotRange@p][[1, 1]];
ar = AspectRatio /. Options[p, AspectRatio] /. Automatic -> 1/GoldenRatio;
ReleaseHold[
Insert[
Hold[plot],
{MeshFunctions -> {"ArcLength"},
ScalingFunctions -> {{pr*#/ar &, ar*#/pr &}, None}},
{1, 3}
]]
]

arclengthmesh@
Plot[Abs[BesselJ[1, x]],
{x, 0, 20},
Filling -> {1 -> Axis, 1 -> Top},
FillingStyle -> {Opacity[1/5, ColorData[1, 1]],
Opacity[1/5, ColorData[1, 2]]},
PlotRange -> {0, 1}, PlotStyle -> Thickness[.01],
Mesh -> 18, MeshStyle -> None, MeshShading -> {Black, White},
AspectRatio -> 1/3] • Clever! I hope this gets more votes. Mar 14, 2017 at 12:45

Like this?

Plot[Evaluate[{Sin[2 \[Pi] x], Sin[2 \[Pi] x]}], {x, 0, 1},
PlotStyle -> {{Dashing[{0.1, 0.1, 1*^-12, 1*^-12}],
Red}, {Dashing[{1*^-12, 0.1, 0.1, 1*^-12}], Black}},
ImageSize -> 500] 