Reputation: 143
I want to make a 3D plot in matplotlib from an already existing 2D plot.
In the 2D plot, there are dots, which are randomly moving inside a circle. Now I have made the axes 3D and as far as I can see, the dots are in a 3D position as well. But they are not moving, and I get an error message: 'ValueError: too many values to unpack (expected 2)'.
I didn't find where I have made the error (I guess somewhere the program still wants only the x,y coordinates).
Could you help me?
from matplotlib import animation
import random
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pyplot
import numpy as np
import matplotlib.pyplot as plt
def get_initial_coordinates():
x_coord =[random.uniform(3, 7) for i in range(n_particles)]
y_coord = [random.uniform(3, 7) for i in range(n_particles)]
z_coord = [random.uniform(3, 7) for i in range(n_particles)]
return x_coord, y_coord, z_coord
def get_initial_velocities():
x_vel = [3 * (np.random.random() - 0.5) * box_width for i in range(n_particles)]
y_vel = [3 * (np.random.random() - 0.5) * box_width for i in range(n_particles)]
z_vel = [3 * (np.random.random() - 0.5) * box_width for i in range(n_particles)]
return x_vel, y_vel, z_vel
def take_step(x_coord, y_coord, z_coord, x_vel, y_vel, z_vel):
for i in range(n_particles):
x_coord[i] += x_vel[i]*dt
y_coord[i] += y_vel[i]*dt
z_coord[i] += z_vel[i]*dt
return x_coord, y_coord,z_coord, x_vel, y_vel,z_vel
n_particles = 40
box_width = 10
n_steps = 5000
dt = 0.001
x_coord, y_coord, z_coord = get_initial_coordinates()
x_vel, y_vel, z_vel = get_initial_velocities()
for i in range(n_steps):
x_coord,y_coord,z_coord,x_vel,y_vel,z_vel= take_step(x_coord,y_coord,z_coord,x_vel,y_vel,z_vel)
#---------------------
fig = pyplot.figure()
ax= Axes3D(fig)
d, = ax.plot([x_coord[i] for i in range(n_particles)],
[y_coord[i] for i in range(n_particles)],
[z_coord[i] for i in range(n_particles)], 'ro')
x_coord, y_coord, z_coord = get_initial_coordinates()
x_vel, y_vel, z_vel = get_initial_velocities()
circle = plt.Circle((5, 5), 3, color='blue', fill=False)
ax.add_artist(circle)
def animate(i):
take_step(x_coord, y_coord, z_coord, x_vel, y_vel, z_vel)
d.set_data([x_coord[i]for i in range(n_particles)],
[y_coord[i]for i in range(n_particles)],
[z_coord[i]for i in range(n_particles)])
return d,
anim = animation.FuncAnimation(fig, animate, frames=200, interval=20)
pyplot.show()
Upvotes: 1
Views: 209
Reputation: 199
set_data()
is hinherited from Line2D
, so it can only take 2 lists, one for x one for y. You have to use .set_3d_properties()
for the z component.
def animate(i):
take_step(x_coord, y_coord, z_coord, x_vel, y_vel, z_vel)
d.set_data([x_coord[i]for i in range(n_particles)],
[y_coord[i]for i in range(n_particles)],
)
d.set_3d_properties([z_coord[i]for i in range(n_particles)])
return d,
Upvotes: 1