简体   繁体   中英

3D scatter plot animation

I am trying to create a 3D animation scatter plot where each point is plotted as a sphere with radius of r proportional to value M (please see the code below), I guess it should be done by using argument s in ax.scatter , but since this value is unique for each (x,y,z), I don't know how to pass that to graph._offsets3d which accepts (x,y,z) touple. This is the first part of the task, the other part is that the data should appear at their specific time t (please see the code below).

  1. I am currently struggling to change the size of each point according to their corresponding value in M , and color code the point with its corresponding time t, do you know how could I do this?

  2. It would my next task to add a play/pause button to the figure and be able to rotate the the graph?

Does anyone have similar experiences that I could benefit from? Many thanks!

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation

#####Data Generation####

# Space Coordinate
X = np.random.random((100,)) * 255 * 2 - 255
Y = np.random.random((100,)) * 255 * 2 - 255
Z = np.random.random((100,)) * 255 * 2 - 255


# Magnitude of each point
M = np.random.random((100,))*-1+0.5

# Time
t = np.sort(np.random.random((100,))*10)

#ID each point should be color coded. Moreover, each point belongs to a cluster `ID`
ID = np.sort(np.round([np.random.random((100,))*5]))

def update_lines(num):
    for i in range (df_IS["EASTING [m]"].size):
        dx = X[i]
        dy = Y[i]
        dz = Z[i] 
        text.set_text("{:d}: [{:.0f}] Mw[{:.2f}]".format(ID[i], t[i],ID[i]))  # for debugging
        x.append(dx) 
        y.append(dy) 
        z.append(dz) 
        graph._offsets3d = (x, y, z) 
        return graph,




fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(111, projection="3d")
graph = ax.scatter(X, Y, Z, color='orange')  # s argument here 
text = fig.text(0, 1, "TEXT", va='top')  # for debugging

ax.set_xlim3d(X.min(), X.max())
ax.set_ylim3d(Y.min(), Y.max())
ax.set_zlim3d(Z.min(),Z.max())

# Creating the Animation object
ani = animation.FuncAnimation(fig, update_lines, frames=200, interval=500, blit=False)
plt.show()

In the animation function was looped by the size of the data frame, but rewrote your code partly because the animation argument is linked to the number of frames. Please correct me if I'm wrong. You can also pass in the size with graph.set_sizes() , which you can specify there. Your size variable had a negative value, so I'm recreating it as an integer. I've used a separate library in part because of my working environment.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation
from IPython.display import HTML # Animation on jupyter lab 
from matplotlib.animation import PillowWriter # For GIF animation 
#####Data Generation####

# Space Coordinate
X = np.random.random((100,)) * 255 * 2 - 255
Y = np.random.random((100,)) * 255 * 2 - 255
Z = np.random.random((100,)) * 255 * 2 - 255

# Magnitude of each point
# M = np.random.random((100,))*-1+0.5
M = np.random.randint(1,70, size=100)
# Time
t = np.sort(np.random.random((100,))*10)

#ID each point should be color coded. Moreover, each point belongs to a cluster `ID`
ID = np.sort(np.round([np.random.random((100,))*5]))

x = []
y = []
z = []
m = []

def update_lines(i):
#     for i in range (df_IS["EASTING [m]"].size):
    dx = X[i]
    dy = Y[i]
    dz = Z[i]
    dm = M[i]
#     text.set_text("{:d}: [{:.0f}] Mw[{:.2f}]".format(ID[i], t[i],ID[i]))  # for debugging
    x.append(dx) 
    y.append(dy) 
    z.append(dz)
    m.append(dm)
    graph._offsets3d = (x, y, z)
    graph.set_sizes(m)
    return graph,

fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(111, projection="3d")
graph = ax.scatter(X, Y, Z, s=M, color='orange')  # s argument here 
text = fig.text(0, 1, "TEXT", va='top')  # for debugging

ax.set_xlim3d(X.min(), X.max())
ax.set_ylim3d(Y.min(), Y.max())
ax.set_zlim3d(Z.min(), Z.max())

# Creating the Animation object
ani = animation.FuncAnimation(fig, update_lines, frames=100, interval=500, blit=False, repeat=False)
# plt.show()
ani.save('test3Dscatter.gif', writer='pillow')
plt.close()
HTML(ani.to_html5_video())

在此处输入图片说明

Edit:

# Time
t = np.sort(np.random.random((100,))*10)

# datapoint for color
cm_name = 'jet'
cm = plt.get_cmap(cm_name, 100)
C = [cm(n) for n in range(cm.N)]

# list for colors add
x = []
y = []
z = []
m = []
c = []

# animation function update

dm = M[i]
dc = C[i] # update

m.append(dm)
c.append(dc) # update

graph._facecolor3d = c # scatter color defined
return graph,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM