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 playing around with the bouncing ball example, and decided to make a 3d version.

I decided to use ParametricPlot3D for a simple independent 3D presentation. However, I found that having an interpolating function as the the first element in the list of three functions passed to ParametricPlot3D doesn't work.

ballz = NDSolve[{z''[t] == -9.81, z[0] == 5, z'[0] == 0,
WhenEvent[z[t] == 0.2, z'[t] -> -0.9 z'[t]]}, z, {t, 0, 10}];

bally = NDSolve[{y''[t] == 0, y[0] == -2, y'[0] == 4, 
WhenEvent[y[t] == 4.8, y'[t] -> -0.9 y'[t]], 
WhenEvent[y[t] == -4.8, y'[t] -> -0.9 y'[t]]}, y, {t, 0, 10}];

Manipulate[
  ParametricPlot3D[{t - 2, y[t] /. bally, z[t] /. ballz}, {t, 0, a}, 
    PlotStyle -> {Gray, Dashed, Thick}, 
    PlotRange -> {{-5, 5}, {-5, 5}, {0, 10}}], 
  {a, 0.025, 10, 0.025}]

enter image description here

The above code works fine, but when I substitute by an interpolation function for the t - 2 term, the function doesn't work. Can this be fixed?

share|improve this question
1  
While you use the term Contourplot3D in your title and text, your code uses ParametricPlot3D , which is not the same thing. –  m_goldberg Jul 28 at 1:02
3  
I don't see how we can help you without seeing the code you used to build your interpolating function and the real plot code that failed. Posting code that worked and then giving a vague description about changes you made doesn't cut it. –  m_goldberg Jul 28 at 1:18
    
Corrected the title. The interpolating functions are the ones you get from the NDSolve. So, replacin t-2 with y[t] /. bally doesn't work, but it doesn't work with ANY interpolating function in the first term. –  Feyre Jul 28 at 10:20
    
It works for me in V10. Exactly what code did not work? –  Michael E2 Jul 28 at 10:28
2  
y[t] /. bally is a list. Use y[t] /. First[bally] to extract the actual interpolating function. –  Simon Woods Jul 28 at 11:02

1 Answer 1

up vote 4 down vote accepted

ParametricPlot3D and ParametricPlot accept a wide range of nested lists of expressions to specify a function or functions to be graphed. Let's discuss ParametricPlot3D. ParametricPlot is similar, with lists of length 2 replacing lists of length 3 where appropriate. There are two types of specifications

List[expr,...]
List[List[...],...]

where expr represents an expression with a head other than List and ... represents expressions possibly nested inside List. Not all inputs will result in a plot, but neither will they result in an error message. My feeling after looking at the plotting examples in the NDSolve documentation is that this flexibility was chosen over a having a more rigorous argument checking, for the convenience of visualization. The output of a simple NDSolve such as in the OP's examples is

List[List[y -> InterpolatingFunction[...]]]

and the result of y[t] /. bally is

List[InterpolatingFunction[...][t]]

so that the y coordinate ends up wrapped in a List. I suppose most people learn to use y[t] /. First[bally] to avoid the extra {}. However, for plotting, it's not strictly necessary.

For each type of input to ParametricPlot3D to produce a plot, it has to satisfy one of the following.

  1. In the first case fn = List[expr,...] where expr is not a List, then Flatten[fn] should be a List of three expressions that are functions of the parameter(s) passed to ParametricPlot3D.

  2. In the second case, fns = List[list1, list2,...], each of list1, etc. should be a List; and for list1 to produce a curve, Flatten[list1] should be a List of three expressions that are functions of the parameter(s), and so on for the other lists.

Here are a few examples:

ParametricPlot3D[{t, {t^2}, {t^3}}, {t, 0, 1}]            (* works -- OP's case *)
ParametricPlot3D[{{t}, {t^2}, {t^3}}, {t, 0, 1}]          (* fails criterion 2 -- no curve *)
ParametricPlot3D[{{{t}, {t^2}, {t^3}}}, {t, 0, 1}]        (* works -- note {{...}} *)
ParametricPlot3D[{{{t}, {t^2}, {t^3}}, {t^2, {{{t^3}}}, {t}}}, {t, 0, 1}] (* works *)

The OP's example

ParametricPlot3D[{t - 2, y[t] /. bally, z[t] /. ballz}, {t, 0, a}]

meets the criterion 1, just as does the first example above. If ballx was another solution to a similar NDSolve, then

ParametricPlot3D[{x[t] /. ballx, y[t] /. bally, z[t] /. ballz}, {t, 0, a}]

would be of the form of the second example,

ParametricPlot3D[{{x[t]}, {y[t]}, {z[t]}}, {t, 0, a}]

which will not produce a plot. (The input is, probably, interpreted as three 1D parametrizations.) To fix it, one could wrap the NDSolve outputs in First: First[ballx], etc. as @SimonWoods mentions in a comment. Or one could put in extra {} as in the third example above:

ballx = NDSolve[{x'[t] == 1, x[0] == -2}, x, {t, 0, 10}];
ParametricPlot3D[{{x[t] /. ballx, y[t] /. bally, z[t] /. ballz}}, {t, 0, 10}]

Mathematica graphics

share|improve this answer
    
I had tried the IPF of the y-function in the x-function first, (which didn't work) and thought it was a more generalized issue. Guess I should have been more thorough when I didn't get what the issue was. Regardless, good explanation, I see the issue now, thanks. –  Feyre Jul 29 at 8:33
    
@Feyre What a coincidence, I tried bally for x at first, too. :) Actually, the issue is not explained in the docs, ASAIK. I didn't really know how extensively forgiving ParametricPlot is of extra {} until I explored your question -- one usually does the simplest thing after all. So thanks for that. –  Michael E2 Jul 29 at 12:54

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.