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).
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?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()