# Plot range of a 2-dimensional function as a function depending on one variable

I want to plot a function of 2 variables x and y, for discrete values of y, like:

myFunc[x_, y_] := Sin[x y]
yvalues={0.1,0.5,1.0,2.0}
Plot[Evaluate@Map[myFunc[x, #] &, yvalues], {x, 0, 5}]


What I want is that the maximum x range (in this case 5) is a function of yvalues, for example, for each value i of yvalues, stop the corresponding plot curve at Cos[yvalues[[i]]].

I need this because in my real case, the function to plot is a 2D interpolation which behaves badly outside some specific intervals depending on y.

Thanks.

-
You can add any of If, Piecewise, Boole and more to your definition of myFunc. – b.gatessucks Aug 19 '14 at 9:46
@b.gatessucks thanks, but it is not possible, since in real life, myFunc is an interpolation function – Santi Aug 19 '14 at 9:47
It should be related to something like this answer mathematica.stackexchange.com/a/20719/6138 – Santi Aug 19 '14 at 9:51
Can't you do simply a table? Table[Plot[Sin[x i], {x, 0, i}], {i, 1, 5}] // Show[#, PlotRange -> All] & – chris Aug 19 '14 at 10:10
otherwise something like this? tt = {Sin[x], Cos[x], Cos[2 x]}; gg = {{0, 1}, {0, 2}, {0, 3}}; MapThread[Plot[#1, Evaluate@{x, Sequence @@ #2}] &, {tt, gg}]//Show – chris Aug 19 '14 at 10:13

Another method with a single plot:

ClearAll[myFunc2];
yvalues = {0.1, 0.5, 1., 2., 3.};

myFunc2[x_?NumericQ, y_?NumericQ] :=
ConditionalExpression[Sin[x y], IntervalMemberQ[Interval[{0, Cos[y]}], x]];
{min, max} = Through[{Min, Max}[Cos[yvalues]]];

Plot[myFunc2[x, #] & /@ yvalues, {x, min, max}, Evaluated -> True, BaseStyle -> Thick,
ImageSize -> 600,  PlotLegends -> "Expressions"] /. myFunc2[a_, b_] :> Sin[ a b]


Edit: Another alternative is to use

myFunc3[x_, y_] :=  ConditionalExpression[Sin[x y], Min[0, Cos[y]] <= x <= Max[0, Cos[y]]];


instead of myFunc2.

-
thanks, that's a nice solution. I still have to understand how this thing with ConditionalExpression and IntervalMemberQ work. – Santi Aug 19 '14 at 21:51
@Santi This is pretty much what I did but using alternative functions. I chose If because it's terse and as just about everyone here knows I like that. IntervalMemberQ takes the place of Cos[#] <= x <= 0 || 0 <= x <= Cos[#] in mine. – Mr.Wizard Aug 19 '14 at 21:56

A method using a single Plot expression:

myFunc[x_, y_] := Sin[x y]
yvalues = {0.1, 0.5, 1.0, 2.0, 3.0};

Block[{x},
Plot[#, {x, -5, 5}, PlotRange -> All, PlotLegends -> Automatic] &[
If[Cos[#] <= x <= 0 || 0 <= x <= Cos[#], myFunc[x, #]] & /@ yvalues
]
]


Notes:

• I use Block to keep x localized.

• I did not programmatically determine the range of the plot; I merely used -5, 5 and let PlotRange -> All clip the result. It would be better (but less clean) to determine the bounds from yvalues. I did not because I did not want to obscure this method. If desired I can add that however.

-
thanks, looks good and the clipping with PlotRange would suit my needs I think. If you want you can post the better method, so I can learn something. – Santi Aug 19 '14 at 21:50
@Santi You're welcome. kguler already posted the calculated bounds method in his answer so I won't duplicate that. – Mr.Wizard Aug 19 '14 at 21:53

Is something like this your intention?

myFunc[x_, y_] := Sin[x y]

yvalues = {0.1, 0.5, 1.0, 2.0, 3.0};

fun = Map[myFunc[x, #] &, yvalues];

lim = Table[Cos[yvalues[[i]]], {i, 1, 5}];

plot =
Table[Plot[fun[[j]], {x, 0, lim[[j]]},
PlotStyle -> {Red, Green, Blue, Orange, Brown}[[j]]], {j, 1, 5}]

Show[plot, PlotRange -> All]


-
yes thanks! I think that would do it. I never thought of using Show, I supposed there was a way to do it inside one single Plot, but this works for me! – Santi Aug 19 '14 at 10:28

If eldo's plot is your desired outcome you could also do:

Show[Plot[Sin[x #], {x, 0, Cos@#}, PlotStyle -> Hue[RandomReal[]]] & /@
yvalues, PlotRange-> All]


Noting Cos2 and Cos[3] are negative.

If you want legends:

With[{col = Hue /@ RandomReal[{0, 1}, 5]},
Legended[
`