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 was hoping to incorporate an If function into a Plot option, as in

Plot[Sin[t], {t, 0, 2 Pi}, Filling -> Axis, 
 FillingStyle -> If[Sin[t] > 0, LightGreen, LightRed]]

or

Plot[Sin[t], {t, 0, 2 Pi}, PlotStyle -> If[Sin[t] > 0, Dashed, Thick]]

to no avail. Is it possible to pass an If to the plot options?

I know that I can manually accomplish the effect via Piecewise, but I have more complicated applications in mind where I would not want to manually precompute the interval(s) on which my piecewise defined function would need to be defined.

share|improve this question
add comment

6 Answers

up vote 2 down vote accepted

Here is yet another crack at this problem.

ConditionalPlot[func_, condition_, varrange_, trueopts_, falseopts_] :=
  Module[{plottrue, plotfalse},
  plottrue = Plot[If[condition, func], varrange, trueopts];
  plotfalse = Plot[If[Not[condition], func], varrange, falseopts];
  Show[plottrue, plotfalse, PlotRange -> All]]

The first argument is the function or list of functions you want to plot. The second argument is the condition you want to apply. The third argument is the variable and range to plot in the form {x,xmin,xmax}. The third and fourth arguments are the options you apply when the condition is true or false, respectively.

For example, the plot you mentioned in your question can be had by

ConditionalPlot[Sin[x], 
 Sin[x] > 0, {x, 0, 2 Pi}, {Filling -> Axis, 
  FillingStyle -> LightGreen, PlotStyle -> Dashed}, {Filling -> Axis, 
  FillingStyle -> LightRed, PlotStyle -> Thick}]

enter image description here

This is versitile, you can give it a compound condition like

ConditionalPlot[Sin[x], 
 Sin[x] > .7 || Sin[x] < -.7, {x, 0, 2 Pi}, {Filling -> Axis, 
  FillingStyle -> LightGreen, PlotStyle -> Dashed}, {Filling -> Axis, 
  FillingStyle -> LightRed, PlotStyle -> Thick}]

enter image description here

You can give it multiple functions to plot

ConditionalPlot[{Sin[x], Cos[x]}, 
 Sin[x] > Cos[x], {x, 0, 4 Pi},
  {PlotStyle -> {Red, Thick}, Axes -> False, Frame -> True, BaseStyle -> 14}, 
      {PlotStyle -> {Black, Thick,Dashed}}]

enter image description here

Note that any global options you want to apply to the image in general should go in the trueopts as it is given to Show first.

share|improve this answer
    
This is quite handy and does what I was looking for. –  JohnD Nov 22 '13 at 18:27
add comment

Not sure there is a direct way to do it but you can split the function up in two:

Plot[{
  If[Sin[t] > 0, Sin[t]],
  If[Sin[t] <= 0, Sin[t]]
  }, {t, 0, 2 Pi},
 Filling -> Axis,
 PlotStyle -> {
     (* Use same color for both so it looks like the same function *)
     Directive[ColorData[1][1], Dashed],
     Directive[ColorData[1][2], Thick]
    },
 FillingStyle -> {1 -> LightGreen, 2 -> LightRed}]

plot

Not that giving FillingStyle two colors it uses one for "below" and the other for "above":

Plot[Sin[t], {t, 0, 2 Pi}, 
 Filling -> Axis, 
 FillingStyle -> {LightRed, LightGreen}]

plot

share|improve this answer
    
The latter is example is quite useful! But at other times I need to adjust the style of the graph based on the function itself. Is it possible to call a plot option which is a function of the input function itself? If so, how? –  JohnD Nov 20 '13 at 20:48
    
@JohnD Don't know if it's even possible for style, but for color-only you can look at ColorFunction –  ssch Nov 20 '13 at 20:49
    
@JohnD, can you give an example of the type of more complex situation you are looking at? The second example ssch gave is pretty general and should work for any function that goes above and below the Filling parameter. –  Jason B Nov 20 '13 at 21:34
    
@JasonB: The second item in the original post is one such example. I agree that works for Filling but I also need to use other options (e.g., PlotStyle). –  JohnD Nov 21 '13 at 1:02
add comment

Applying the method I used here and here, we can use ParametricPlot with MeshShading:

 ParametricPlot[{t, u Sin[t]}, {t, 0, 2 Pi}, {u, 0, 1}, 
  MeshFunctions -> {#2 &}, Mesh -> {{0}}, MeshShading -> {LightRed, LightGreen},
  AspectRatio -> 1/GoldenRatio, PlotRange -> All, Frame -> False]

Mathematica graphics

Since one may specify arbitrary MeshFunctions, it does provide some flexibility.

ParametricPlot[{t, u Sin[t]}, {t, 0, 2 Pi}, {u, 0, 1},
 MeshFunctions -> {#2 - Cos[2 #1] &}, Mesh -> {{0}}, MeshShading -> {LightRed, LightGreen},
 AspectRatio -> 1/GoldenRatio,  PlotRange -> All, Frame -> False]

Mathematica graphics


One of the comments mentions a desire to control the PlotStyle. MeshFunctions and MeshShading may be used with Plot to control the style of the plotted line.

With[{meshfns = {#2 - Cos[2 #1] &}, mesh = {{0}}},
 Show[
  ParametricPlot[{t, u Sin[t]}, {t, 0, 2 Pi}, {u, 0, 1},
   BoundaryStyle -> None,
   MeshFunctions -> meshfns, Mesh -> mesh, 
   MeshShading -> {LightRed, LightGreen}, 
   AspectRatio -> 1/GoldenRatio, PlotRange -> All, Frame -> False],
  Plot[Sin[t], {t, 0, 2 Pi},
   MeshFunctions -> meshfns, Mesh -> mesh, MeshStyle -> None,
   MeshShading -> {Directive[Red, Thick], Directive[Green, Thick]}]
  ]]

Mathematica graphics

share|improve this answer
add comment

One more way!

colors = {Red, Green};
Plot[Evaluate@{If[Sin[t] > 0, Sin[t]], If[Sin[t] <= 0, Sin[t]]}, {t,0, 2 Pi},
Filling -> Axis,PlotStyle -> Transpose@{{Dashed, Thick}, colors}, 
FillingStyle -> MapIndexed[#2 -> Directive[Opacity[0.25], #] &, colors]
]

enter image description here

share|improve this answer
add comment

I would make two different plots and combine them with a Show command, like

Show[Plot[Sin[t], {t, 0, 2 Pi}, Filling -> Axis, 
  PlotStyle->Dashed,FillingStyle -> LightGreen, PlotRange -> {0, All}], 
 Plot[Sin[t], {t, 0, 2 Pi}, Filling -> Axis, FillingStyle -> LightRed,
   PlotStyle->Thick,PlotRange -> {All, 0}], PlotRange -> All]

enter image description here

share|improve this answer
    
The downside to this is if the function and/or condition (in general) is complicated, I have to manually precompute the pieces, which I am trying to avoid. –  JohnD Nov 20 '13 at 20:52
    
@JohnD, the two examples you gave are simple enough that this method works great. What is an example where this method would get too tedious? It's possible that even for the more complicated tasks you have envisioned, we could make a list of Plots which we create using Table, and then feed that list to Show. –  Jason B Nov 21 '13 at 1:15
add comment

Another way is to generate the plot for each domain/range that are specified. Then thread them together with Show function.

A simple example:

Show[
     RegionPlot[x^2 + y^3 < 2, {x, -2, 2}, {y, -2, 2}, PlotStyle -> Red],
     RegionPlot[x^2 + y^3 > 3, {x, -2, 2}, {y, -2, 2}]
]

region

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.