Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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]

enter image description here

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]

enter image description here

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?

share

2 Answers 2

up vote 12 down vote accepted

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]

Plot

share
    
Filling is optional... –  whuber Nov 22 '12 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 '12 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[2]]]

plot with alternating colors

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[2]]]

plot with "uniform" alternating colors

share
    
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 '12 at 0:14
    
Is the second version more suitable, @Jason? –  J. M. Nov 22 '12 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 '12 at 0:27
2  
Oh well, gave it a college try at least... –  J. M. Nov 22 '12 at 0:33

This site is currently not accepting new answers.