# Conditional options in Plot [duplicate]

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.

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}]


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}]


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}}]


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.

• This is quite handy and does what I was looking for. – JohnD Nov 22 '13 at 18:27

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}]


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}]


• 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

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]


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]


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,
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]}]
]]


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


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]


• 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

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}]
]