5
$\begingroup$

While I was thinking about Plot with a reference line and shaded / colored region, I came up with

Plot[{i, 4, 6, 8, 10}, {i, 0, 10}, 
Filling -> {5 -> {4}, 4 -> {3}, 3 -> {2}, 2 -> Bottom}]

enter image description here

as an easy solution strategy directly from the help instructions.

One can try with Table to virtually automate the Filling Stuff, but will fail miserably on n -> Bottom

Table[n -> {n - 1}, {n, 3, 5, 1}]

{3 -> {2}, 4 -> {3}, 5 -> {4}}

Plot[{i, 4, 6, 8, 10}, {i, 0, 10}, 
Filling -> Table[n -> {n - 1}, {n, 3, 5, 1}]]

enter image description here

So, how to add n -> Bottom to a Table ?

$\endgroup$
5
  • $\begingroup$ Does it have to be part of the table? And you can't add another plotline? $\endgroup$
    – Feyre
    Commented Jul 16, 2016 at 8:53
  • $\begingroup$ i.e. Plot[{i, 0, 4, 6, 8, 10}, {i, 0, 10}, Filling -> Table[n -> {n - 1}, {n, 3, 6, 1}]] is no good? $\endgroup$
    – Feyre
    Commented Jul 16, 2016 at 8:58
  • 5
    $\begingroup$ What's wrong with simply adding an If? Table[n -> If[n == 2, Bottom, {n - 1}], {n, 2, 5, 1}]? Don't try to make a complex problem out of a simple one. $\endgroup$ Commented Jul 16, 2016 at 9:05
  • $\begingroup$ @Feyre go ahead and answer! $\endgroup$
    – user9660
    Commented Jul 16, 2016 at 9:29
  • $\begingroup$ @IstvánZachar go ahead and answer! $\endgroup$
    – user9660
    Commented Jul 16, 2016 at 9:29

3 Answers 3

9
$\begingroup$

When I decide to automate a special kind of plot, I try to produce something that can handle more than the particular special case I have at hand. For this question, I think the following makes a good start.

SetAttributes[myPlot, HoldAll]
myPlot[expr_, hlines : {__}, domain_, opts : OptionsPattern[]] :=
  Module[{n, fills, plt},
    n = Length[hlines] - 1;
    fills =
      Append[If[n == 0, {}, Table[i -> {i - 1}, {i, 3, n + 2}]], 2 -> Bottom];
    plt = Prepend[Sort[hlines], expr];
    Plot[Evaluate @ plt, domain,
      Evaluate @ FilterRules[{opts, Filling -> fills}, Options[Plot]]]]

Of course, it handles the example given in the question.

myPlot[x, {4, 6, 8, 10}, {x, 0, 10}]

plot1

Other tests

Only on horizontal line.

myPlot[x, {5}, {x, 0, 10}]

plot2

Horizontal lines not ordered.

myPlot[x, {10, 4, 8, 6}, {x, 0, 10}]

plot1

Can accept plot options.

myPlot[8 Abs[Sin[x]], {4, 8, 6}, {x, 0, 2 π}, PlotStyle -> {Red, Blue, Green, Black}]

plot3

Note

I say this is the just start of a full implementation because there are argument patterns that Plot handles that myPlot won't. For example, suppose you wanted to plot several expressions as well a list of horizontals. As coded above, myPlot handles that badly. It would not be all that hard to add support for multiple-expression plots, but my point is that adding support for multiple expressions is only one of many features that might need to be added to make myPlot really robot.

$\endgroup$
2
  • 1
    $\begingroup$ Nice, but I'd like to see the primary plot line above the horizontals. +1 of course. $\endgroup$
    – Mr.Wizard
    Commented Jul 16, 2016 at 12:17
  • 1
    $\begingroup$ @Mr.Wizard. I would like that too. Certainly one of the many but important details that needs to be considered when fooling with Plot. I could make the excuse that I was only preserving the way OP handled layering, but that would be a cop-out -- I simply missed that particular detail. $\endgroup$
    – m_goldberg
    Commented Jul 16, 2016 at 12:32
7
$\begingroup$
Plot[{i, 0, 4, 6, 8, 10}, {i, 0, 10}, Filling -> Table[n -> {n - 1}, {n, 3, 6, 1}]]

enter image description here

Plot[{i, 4, 6, 8, 10}, {i, 0, 10}, 
 Filling -> 
  Flatten[{Table[n -> {n - 1}, {n, 3, 6, 1}], {2 -> Bottom}}]]

or

Plot[{i, 4, 6, 8, 10}, {i, 0, 10}, 
 Filling -> Table[n -> {n - 1}, {n, 2, 6, 1}] /. {1} -> Bottom // 
  Evaluate]

enter image description here

$\endgroup$
1
$\begingroup$

Use Table as in your question but add 2-> Bottom to the list.

Join[Table[n -> {n - 1}, {n, 3, 5, 1}], {2 -> Bottom}]

(* {3 -> {2}, 4 -> {3}, 5 -> {4}, 2 -> Bottom} *)

Plot[{i, 4, 6, 8, 10}, {i, 0, 10}, 
 Filling -> Join[Table[n -> {n - 1}, {n, 3, 5, 1}], {2 -> Bottom}]]

Mathematica graphics

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.