4
$\begingroup$

I would like to display the positions of a collection of particles as a function of time (animated) and color code them based on their velocities. For example, consider 10 particles moving in a 2D harmonic oscillator:

velocity = Flatten[(Sqrt[x'[t]^2 + y'[t]^2] /. position)];
Num = 10;
position0 = 
  Table[{RandomReal[{-5, 5}], RandomReal[{-5, 5}]}, {i, 1, Num}];

ωx = 1; ωy = 1.07;
position = Table[
   NDSolve[{x''[t] == -ωx^2 x[t], x[0] == position0[[i, 1]], x'[0] == 0, 
     y''[t] == -ωy^2 y[t], y[0] == position0[[i, 2]], 
     y'[0] == 0}, {x, y}, {t, 0, 10}], {i, 1, Num}];
velocity = Flatten[(Sqrt[x'[t]^2 + y'[t]^2] /. position)];

I can then plot a single particle's trajectory colored by its velocity:

ParametricPlot[Evaluate[{x[t], y[t]} /. position[[2]]], {t, 0, 10},
 ColorFunction -> 
  Function[{x, y, t}, 
   ColorData[{"ThermometerColors", {0, 5}}][velocity[[2]]]], 
 ColorFunctionScaling -> False
 ]

Particle trajectory in harmonic well, colored by velocity

But what I would like to do is plot the points using ListPlot, and color code each point by its velocity as a function of time. I've started:

Animate[
 ListPlot[Table[{x[t], y[t]} /. position[[i, 1]], {i, 1, Num}],
   PlotRange -> {{-5, 5}, {-5, 5}}, Joined -> True, 
   ColorFunction -> 
    Function[{i, x, y, t}, 
     ColorData[{"ThermometerColors", {0, 5}}][velocity]]], 
   ColorFunctionScaling -> False] /. Line -> Point,
 {t, 0, 10}, AnimationRunning -> False]

I get the animation right but the colors do not appear -- I'm sure I'm not addressing the ColorFunction correctly but I'm not sure how to get it to index by point rather than by one of the continuous variables (eg. x or y).

Point spread of 10 particles

$\endgroup$
1

1 Answer 1

1
$\begingroup$

I could not use your code, but since you are getting the animation right already, consider doing something similar to this answer: I'll use some random data and omit the t-dependence:

positions = RandomReal[{-4, 4}, {10, 2}];
velocities = RandomReal[{0, 5}, {10}];

Now use Point to get the colors right:

Graphics[MapThread[{ColorData[{"ThermometerColors", {0, 5}}][#1], Point[#2]} &, {velocities, positions}], Axes -> True]

Edit: I see that ListPlot might perform better than the above solution, so here is an alternative solution using ListPlot. The trick is to use Style for each point:

Let's first generate some random data (I do not claim that these values make any sense!):

startpositions = RandomReal[{-4, 4}, {10, 2}];
positions[t_] := Cos[t] Exp[-t/10] startpositions;
velocities[t_] := Abs[-(1/10) E^(-t/10) (Cos[t] + 10 Sin[t])] Norm /@ startpositions;

Now you can animate it as follows.

Animate[ListPlot[
Table[Style[{positions[t][[i, 1]], positions[t][[i, 2]]}, 
ColorData[{"ThermometerColors", {0, 5}}][velocities[t][[i]]]], {i,
10}], PlotRange -> {{-5, 5}, {-5, 5}}], {t, 0, 10}]

Please note that I didn't pay any attention to the scaling of the color function (which assumes that the velocities are between 0 and 5).

$\endgroup$
2
  • $\begingroup$ Thank you for your response. I've seen the answer you mentioned and I suppose I should clarify that I'm hoping to avoid explicit use of the Graphics function and making a giant array of positions and velocities at different times. I'd like to be able to use ListPlot because I suspect it will be faster than telling Graphics to make each point individually (I could easily be wrong about that) and I would like to be able to evaluate the interpolation functions at time t to generate both the positions and velocities. $\endgroup$
    – SeanM
    Commented Oct 18, 2017 at 17:24
  • $\begingroup$ I edited the answer and use ListPlot now, as it might really be faster than the previous suggestion. The t-dependence can be incorporated quite easily and you will adjust it for your case, of course. $\endgroup$
    – M. Stern
    Commented Oct 18, 2017 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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