I have the following $3$ piecewise functions, and I would like that f1
, f2
and f3
have $3$ different colours:
Plot[ Piecewise[{{{f1, f2,f3}, B < 1/2}, {{f1, f2,f3}, B > 1/2}}], {B, 0, 1}]
How can I do that?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityI have the following $3$ piecewise functions, and I would like that f1
, f2
and f3
have $3$ different colours:
Plot[ Piecewise[{{{f1, f2,f3}, B < 1/2}, {{f1, f2,f3}, B > 1/2}}], {B, 0, 1}]
How can I do that?
To colorize the plot you need the list of piecewices not piecewise of lists. See the following example:
pw = Piecewise[{{{x^2, 1}, x < 1}, {{2 - x, x}, x > 1}}]
Plot[pw, {x, 0, 2}]
You can convert pw
to the list of piecewices manually or automatically by
pw2 = Piecewise /@ Transpose[Thread /@ pw[[1]]]
Plot[pw2, {x, 0, 2}]
Alternative to Michael's post-processing method:
f1 = B; f2 = B^2; f3 = 1 - B^3;
Module[{n = 0},
Plot[Piecewise[{{{f1, f2, f3}, B < 1/2}, {{f1, f2, f3}, B > 1/2}}], {B, 0, 1}] /.
Line[p_] :> {ColorData[1, Ceiling[n += 1/2]], Line[p]}]
I'm not sure of the exact parameters of this problem. Let's suppose that, for whatever reason, the function comes as Piecewise
function whose values are triples of real numbers.
Then one way is to convert the Piecewise
function into three Piecewise
functions and proceed as in ybeltukov's answer.
pwToVec[pw_Piecewise] /; ArrayQ[Append[pw[[1, All, 1]], Last[pw]]] :=
Piecewise /@ Transpose[Thread /@ Append[First[pw], {Last[pw], True}]];
pwToVec[pw_Piecewise] /; ArrayQ[pw[[1, All, 1]]] :=
Piecewise[#, Last@pw] & /@ Transpose[Thread /@ First@pw];
Module[{f1 = B, f2 = B^2, f3 = 1 - B^3, plot},
pw = Piecewise[{{{f1, f2, f3}, B < 1/2}, {{f1, f2, f3}, B > 1/2}}];
Plot[Evaluate@pwToVec[pw], {B, 0, 1}]
]
One drawback is the use of Evaluate
, which is necessary to get the different styles.
Another way is to post-process the normal plot to add styling to the lines.
Module[{f1 = B, f2 = B^2, f3 = 1 - B^3, plot},
plot = Plot[Piecewise[{{{f1, f2, f3}, B < 1/2}, {{f1, f2, f3}, B > 1/2}}], {B, 0, 1}];
ListLinePlot[
Flatten[Transpose@Partition[#, Length[#]/3], 1] &@
Cases[plot, Line[p_] :> p, Infinity],
PlotStyle -> {Red, Green, Blue}, Options[plot]]
]
A potential drawback is that the code assumes that the Lines
are generated by Plot
in a certain order: The lines for the first coordinate are followed by the lines for the second coordinate, which in turn are followed by the lines for the third. These have the same number of pieces (which is likely to be stable, since a single Piecewise
is being plotted).
Hint: The Flatten[Transpose@Partition[...]]
simply reorders the lines, so that as ListPlot
cycles through the list of PlotStyles
, the same style gets matched to the lines of each function.
pwToVec
doesn't work with Piecewise[{{{x^2, 1}, x < 1}, {{2 - x, x}, True}}]
. That's why I suggested a short, but not the general solution :)
$\endgroup$
Nov 12, 2013 at 15:18
Simplify`PWToUnitStep
You can also use the function Simplify`PWToUnitStep
to transform your single 3D piecewise function to a list of functions:
pw = Piecewise[{{{B, B^3, 1 - B^3}, B < 1/2 || B > 1/2}}];
Plot[Evaluate@Simplify`PWToUnitStep[pw], {B, 0, 1},
PlotStyle -> {Red, Green, Blue},
BaseStyle -> Directive[CapForm["Butt"], Thick]]
If you want to remove the gap use the option Exclusions -> None
to get