<blockquote>
  <p>After that I want to make it a bit complicated. I have the stars size and mass as well. I was wondering if I can change the size of the circles in the plot according to the radius and use different Colors for different mass range?</p>
</blockquote>

<p>That part has been addressed in previous questions and answers here, I remember reading maybe a year ago (+/- 0.9 years).</p>

<hr>

<p>Here is something you may find helpful reprinted from <a href="https://stackoverflow.com/a/34572718/3904031">my answer in Stack Overflow</a>. It's based on astronomer and data scientist <a href="https://jakevdp.github.io/pages/about.html" rel="nofollow noreferrer">Jake VanderPlas</a>' blogpost <a href="https://jakevdp.github.io/blog/2013/02/16/animating-the-lorentz-system-in-3d/" rel="nofollow noreferrer">from 2013</a>.</p>

<p>For your needs keep the dots but not the lines. What I recommend is that you start from this and get as far as you can, then ask a question in Stack Overflow <em>showing what you've tried and explaining what you still need</em>.</p>

<blockquote>
  <p>Here is the Lorenz attractor both in 3D and animated. The script is in the following link (along with many goodies) in Jake VanderPlas' Pythonic Perambulations. You can learn a lot by going line-by-line through the script - it's an elegant use of <code>matplotlib</code> objects.</p>
  
  <p><a href="https://jakevdp.github.io/blog/2013/02/16/animating-the-lorentz-system-in-3d/" rel="nofollow noreferrer">https://jakevdp.github.io/blog/2013/02/16/animating-the-lorentz-system-in-3d/</a></p>
  
  <p>I added these two lines just before <code>return</code> in the <code>animate</code> function, and then used <a href="http://imagej.nih.gov/ij/" rel="nofollow noreferrer">ImageJ</a> to import the "image stack" and save the "animated GIF":</p>
</blockquote>

<pre><code>fname = "Astro_Jake_" + str(i+10000)[1:]
fig.savefig(fname)
</code></pre>

<blockquote>
  <p><strong>Note:</strong> For OSX it seems to be necessary to set <code>blit = False</code> in <code>animation.FuncAnimation</code>.</p>
  
  <p><a href="https://i.sstatic.net/CsiCG.gif" rel="nofollow noreferrer"><img src="https://i.sstatic.net/CsiCG.gif" alt="Astro Jake"></a></p>
  
  <p>Here is a minimal, simplified example of plotting lines in 3D based on the above:</p>
</blockquote>

<pre><code>def lorentz_deriv((x, y, z), t0, sigma=10., beta=8./3, rho=28.0):
    """Compute the time-derivative of a Lorentz system."""
    return [sigma * (y - x), x * (rho - z) - y, x * y - beta * z]

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.integrate import odeint as ODEint

x = np.linspace(0, 20, 1000)
y, z = 10.*np.cos(x), 10.*np.sin(x) # something simple

fig = plt.figure()
ax = fig.add_subplot(1,2,1,projection='3d')
ax.plot(x, y, z)

# now Lorentz
times = np.linspace(0, 4, 1000) 

start_pts = 30. - 15.*np.random.random((20,3))  # 20 random xyz starting values

trajectories = []
for start_pt in start_pts:
    trajectory = ODEint(lorentz_deriv, start_pt, times)
    trajectories.append(trajectory)

ax = fig.add_subplot(1,2,2,projection='3d')
for trajectory in trajectories:
    x, y, z = trajectory.T  # transpose and unpack 
    # x, y, z = zip(*trajectory)  # this also works!
    ax.plot(x, y, z)

plt.show()
</code></pre>

<p>I wrote this before I knew of PIL. Apparently you can use PIL to generate your GIFs instead of using an external program like I did.</p>

<p>See </p>

<ul>
<li><a href="https://blog.zhaytam.com/2018/08/21/creating-gifs-using-python-pillow/" rel="nofollow noreferrer">Creating GIFs in Python Using Pillow (PIL Fork)</a></li>
<li><a href="https://pythonprogramming.altervista.org/create-an-animated-gif-with-pil/" rel="nofollow noreferrer">https://pythonprogramming.altervista.org/create-an-animated-gif-with-pil/</a></li>
<li><a href="https://pythonprogramming.altervista.org/png-to-gif/" rel="nofollow noreferrer">https://pythonprogramming.altervista.org/png-to-gif/</a></li>
</ul>

<p>and have fun!</p>

<p>An example of a GIF with stars in it from the first blogpost (Nyan Cat):</p>

<p><a href="https://i.sstatic.net/7uYc6.gif" rel="nofollow noreferrer"><img src="https://i.sstatic.net/7uYc6.gif" alt="An example of a GIF (Nyan Cat)"></a></p>

CC BY-SA 4.0
2020-05-01T01:45:45.163Z
2020-05-01T04:04:32.963Z
2020-05-01T04:04:32.963Z
uhoh
<p>Hi I did manage to write the code. Here is what I did </p>

<pre><code>import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.animation as animation
import pandas as pd

df1=pd.read_pickle("properties.csv")
x=np.array(df1['x'])*3.24078e-17
y=np.array(df1['y'])*3.24078e-17
z=np.array(df1['z'])*3.24078e-17

data=[]
for i in range(len(x)):
    blank=[]
    for j in range(len(x[i])):
        dummy=[]
        dummy.append(x[i][j])
        dummy.append(y[i][j])
        dummy.append(z[i][j])
        blank.append((dummy))

    data.append(np.array(blank))



def animate_scatters(iteration, data, scatters):
    for i in range(data[0].shape[0]):
        scatters[i]._offsets3d = (data[iteration][i,0:1], data[iteration][i,1:2], data[iteration][i,2:])
    return scatters

def main(data, save=False):
    fig = plt.figure()
    ax = p3.Axes3D(fig)

    # Initialize scatters
    scatters = [ ax.scatter(data[0][i,0:1], data[0][i,1:2], data[0][i,2:]) for i in range(data[0].shape[0]) ]

    # Number of iterations
    iterations = len(data)

    # Setting the axes properties
    ax.set_xlim3d([-10, 10])
    ax.set_xlabel('X')

    ax.set_ylim3d([-10, 10])
    ax.set_ylabel('Y')

    ax.set_zlim3d([-10, 10])
    ax.set_zlabel('Z')

    ax.set_title('Nuclear Star Cluster')

    # Provide starting angle for the view.
    ax.view_init(25, 10)

    ani = animation.FuncAnimation(fig, animate_scatters, iterations, fargs=(data, scatters),
                                       interval=50, blit=False, repeat=True)

    if save:
        Writer = animation.writers['ffmpeg']
        writer = Writer(fps=30, metadata=dict(artist='Me'), bitrate=1800, extra_args=['-vcodec', 'libx264'])
        ani.save('3d-scattered-animated.mp4', writer=writer)

    plt.show()

#print data[1]
main(data, save=True)
</code></pre>

<p>Now my problem is my data shape is changing with time, the number of particles is getting reduced. How do I incorporate that in the code?</p>

CC BY-SA 4.0
2020-05-01T09:04:55.680Z
Is this an answer? Shouldn't this be part of the question? Then edit your question accordingly.
planetmaker
CC BY-SA 4.0
2020-05-01T10:24:12.917Z
@planetmaker Good point. However, this is looking more like a coding question now, and it may be better to ask it on Stack Overflow, where there are plenty of Python users who know matplotlib. OTOH, asking on SO can be a nerve-wracking experience, we're a bit gentler here on Astronomy. ;)
PM 2Ring
CC BY-SA 4.0
2020-05-01T10:24:17.663Z
Okay well I think this is the end of the road for Astronomy SE for your question, since this is no longer even a little bit about Astronomy. You have some experience with Stack Overflow, they need fairly specific questions, and there is also [Code Review SE](https://codereview.stackexchange.com/) and they require *running code* that only needs improvement. We should't post follow up questions in answer posts.
uhoh
CC BY-SA 4.0
2020-05-01T10:25:33.590Z
@PM2Ring ya that's why I posted at least something *here* to at least get them started.
uhoh
CC BY-SA 4.0
2020-05-01T10:35:24.987Z
I've  only had a brief look at your code, but I noticed a couple of things. There's no need to import `pandas` just to read a .csv file if you aren't actually using any other Pandas features. You can use the `DictReader` in the `csv` module for that. Also, your `data` conversion looks very inefficient. If you find yourself using `for` loops on a Numpy array, you're probably doing it wrong. Especially nested `for` loops.
PM 2Ring
CC BY-SA 4.0
2020-05-01T14:59:32.053Z
@PM2Ring There is nothing wrong using for loop or nested for loop with numpy arrays. I am just grouping the [x,y,z] for each particle which could have been done using np.hstack as well I guess
Arpan Das
CC BY-SA 4.0
2020-05-01T23:58:22.963Z
@ArpanDas when your data gets big you will have much better results if you follow that advice. "There's nothing wrong" will turn into "My script takes forever to run" to which the answer will be "You're *definitely* doing it wrong." Learn to let numpy do the work for you because numpy executes fast compiled code whereas nested python loops are far slower. Stacking and moving the order of axes of arrays have simple numpy syntax, and when you are done you can consider using `.copy()` to make a new instance of your reordered array (if you have enough memory) if caching/paging slows you down.
uhoh
CC BY-SA 4.0
2020-05-01T08:46:47.340Z
2020-05-01T08:46:47.340Z
Arpan Das
<p>I am trying to make a 3-D animation of stars' position vs time. I have the information of the stars' x, y and z co-ordinates over time. I was looking at the example of Matplotlib and did understood what I need to do but I don't want the connecting lines between different times. All I need is to show the position of the stars at different time and make a movie of it. This is the example I was looking at </p>

<p><a href="https://matplotlib.org/gallery/animation/simple_3danim.html" rel="nofollow noreferrer">https://matplotlib.org/gallery/animation/simple_3danim.html</a></p>

<p>After that I want to make it a bit complicated. I have the stars size and mass as well. I was wondering if I can change the size of the circles in the plot according to the radius and use different Colors for different mass range? </p>

CC BY-SA 4.0
2020-05-01T01:18:15.287Z
The answer you seek is going to be in the mplo3d documentation, not on this stackexchange.
AtmosphericPrisonEscape
<amateur-observing><python><night-sky><visualization>
How to create 3D animation of particles position vs time in python?
Arpan Das
# How to create 3D animation of particles position vs time in python?

(Asked by: username_0 on 2020-04-30)

I am trying to make a 3-D animation of stars' position vs time. I have the information of the stars' x, y and z co-ordinates over time. I was looking at the example of Matplotlib and did understood what I need to do but I don't want the connecting lines between different times. All I need is to show the position of the stars at different time and make a movie of it. This is the example I was looking at

<https://matplotlib.org/gallery/animation/simple_3danim.html>

After that I want to make it a bit complicated. I have the stars size and mass as well. I was wondering if I can change the size of the circles in the plot according to the radius and use different Colors for different mass range?

**Tags:** amateur-observing, python, night-sky, visualization
> **Comments:**
> **username_1**: The answer you seek is going to be in the mplo3d documentation, not on this stackexchange.  

---

## 2 answers

### Answer by username_2 on 2020-05-01. Score: 3

After that I want to make it a bit complicated. I have the stars size and mass as well. I was wondering if I can change the size of the circles in the plot according to the radius and use different Colors for different mass range?

That part has been addressed in previous questions and answers here, I remember reading maybe a year ago (+/- 0.9 years).

Here is something you may find helpful reprinted from my answer in Stack Overflow. It's based on astronomer and data scientist Jake VanderPlas' blogpost from 2013.
For your needs keep the dots but not the lines. What I recommend is that you start from this and get as far as you can, then ask a question in Stack Overflow showing what you've tried and explaining what you still need.

Here is the Lorenz attractor both in 3D and animated. The script is in the following link (along with many goodies) in Jake VanderPlas' Pythonic Perambulations. You can learn a lot by going line-by-line through the script - it's an elegant use of matplotlib objects.
https://jakevdp.github.io/blog/2013/02/16/animating-the-lorentz-system-in-3d/
I added these two lines just before return in the animate function, and then used ImageJ to import the "image stack" and save the "animated GIF":

fname = "Astro_Jake_" + str(i+10000)[1:]
fig.savefig(fname)


Note: For OSX it seems to be necessary to set blit = False in animation.FuncAnimation.

Here is a minimal, simplified example of plotting lines in 3D based on the above:

def lorentz_deriv((x, y, z), t0, sigma=10., beta=8./3, rho=28.0):
    """Compute the time-derivative of a Lorentz system."""
    return [sigma * (y - x), x * (rho - z) - y, x * y - beta * z]

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.integrate import odeint as ODEint

x = np.linspace(0, 20, 1000)
y, z = 10.*np.cos(x), 10.*np.sin(x) # something simple

fig = plt.figure()
ax = fig.add_subplot(1,2,1,projection='3d')
ax.plot(x, y, z)

# now Lorentz
times = np.linspace(0, 4, 1000) 

start_pts = 30. - 15.*np.random.random((20,3))  # 20 random xyz starting values

trajectories = []
for start_pt in start_pts:
    trajectory = ODEint(lorentz_deriv, start_pt, times)
    trajectories.append(trajectory)

ax = fig.add_subplot(1,2,2,projection='3d')
for trajectory in trajectories:
    x, y, z = trajectory.T  # transpose and unpack 
    # x, y, z = zip(*trajectory)  # this also works!
    ax.plot(x, y, z)

plt.show()

I wrote this before I knew of PIL. Apparently you can use PIL to generate your GIFs instead of using an external program like I did.
See 

Creating GIFs in Python Using Pillow (PIL Fork)
https://pythonprogramming.altervista.org/create-an-animated-gif-with-pil/
https://pythonprogramming.altervista.org/png-to-gif/

and have fun!
An example of a GIF with stars in it from the first blogpost (Nyan Cat):


---

### Answer by username_0 on 2020-05-01. Score: -1

Hi I did manage to write the code. Here is what I did 
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.animation as animation
import pandas as pd

df1=pd.read_pickle("properties.csv")
x=np.array(df1['x'])*3.24078e-17
y=np.array(df1['y'])*3.24078e-17
z=np.array(df1['z'])*3.24078e-17

data=[]
for i in range(len(x)):
    blank=[]
    for j in range(len(x[i])):
        dummy=[]
        dummy.append(x[i][j])
        dummy.append(y[i][j])
        dummy.append(z[i][j])
        blank.append((dummy))

    data.append(np.array(blank))



def animate_scatters(iteration, data, scatters):
    for i in range(data[0].shape[0]):
        scatters[i]._offsets3d = (data[iteration][i,0:1], data[iteration][i,1:2], data[iteration][i,2:])
    return scatters

def main(data, save=False):
    fig = plt.figure()
    ax = p3.Axes3D(fig)

    # Initialize scatters
    scatters = [ ax.scatter(data[0][i,0:1], data[0][i,1:2], data[0][i,2:]) for i in range(data[0].shape[0]) ]

    # Number of iterations
    iterations = len(data)

    # Setting the axes properties
    ax.set_xlim3d([-10, 10])
    ax.set_xlabel('X')

    ax.set_ylim3d([-10, 10])
    ax.set_ylabel('Y')

    ax.set_zlim3d([-10, 10])
    ax.set_zlabel('Z')

    ax.set_title('Nuclear Star Cluster')

    # Provide starting angle for the view.
    ax.view_init(25, 10)

    ani = animation.FuncAnimation(fig, animate_scatters, iterations, fargs=(data, scatters),
                                       interval=50, blit=False, repeat=True)

    if save:
        Writer = animation.writers['ffmpeg']
        writer = Writer(fps=30, metadata=dict(artist='Me'), bitrate=1800, extra_args=['-vcodec', 'libx264'])
        ani.save('3d-scattered-animated.mp4', writer=writer)

    plt.show()

#print data[1]
main(data, save=True)

Now my problem is my data shape is changing with time, the number of particles is getting reduced. How do I incorporate that in the code?

> **Comments:**
> **username_3**: Is this an answer? Shouldn't this be part of the question? Then edit your question accordingly.  
> **username_4**: @planetmaker Good point. However, this is looking more like a coding question now, and it may be better to ask it on Stack Overflow, where there are plenty of Python users who know matplotlib. OTOH, asking on SO can be a nerve-wracking experience, we're a bit gentler here on Astronomy. ;)  
> **username_2**: Okay well I think this is the end of the road for Astronomy SE for your question, since this is no longer even a little bit about Astronomy. You have some experience with Stack Overflow, they need fairly specific questions, and there is also [Code Review SE](https://codereview.stackexchange.com/) and they require *running code* that only needs improvement. We should't post follow up questions in answer posts.  
> **username_2**: @PM2Ring ya that's why I posted at least something *here* to at least get them started.  
> **username_4**: I've  only had a brief look at your code, but I noticed a couple of things. There's no need to import `pandas` just to read a .csv file if you aren't actually using any other Pandas features. You can use the `DictReader` in the `csv` module for that. Also, your `data` conversion looks very inefficient. If you find yourself using `for` loops on a Numpy array, you're probably doing it wrong. Especially nested `for` loops.  
> **username_0**: @PM2Ring There is nothing wrong using for loop or nested for loop with numpy arrays. I am just grouping the [x,y,z] for each particle which could have been done using np.hstack as well I guess  
> **username_2**: @ArpanDas when your data gets big you will have much better results if you follow that advice. "There's nothing wrong" will turn into "My script takes forever to run" to which the answer will be "You're *definitely* doing it wrong." Learn to let numpy do the work for you because numpy executes fast compiled code whereas nested python loops are far slower. Stacking and moving the order of axes of arrays have simple numpy syntax, and when you are done you can consider using `.copy()` to make a new instance of your reordered array (if you have enough memory) if caching/paging slows you down.  

---

