I came to this problem when I tried to adjust the limits of the axis in the 3D animation. It seemed that the range of the limits on the screen is not what I want, but the output of the limits on the console was Ok. The plot line could not be displayed well in the axes. I'm very confused, because I don't even know where the problem is.
Here's my code.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button, TextBox
from matplotlib import animation
x = np.array([0.0])
y = np.array([1.0])
z = np.array([0.0])
v = np.array([1.0, 0.0, 1.0])
tmax = 1
tmin = 0
fig2 = plt.figure()
# fig2.set_visible(False)
ax = fig2.add_axes([0.075, 0.1, 0.6, 0.8],projection='3d')
def set_axes_equal(ax: plt.Axes):
limits = np.array([ax.get_xlim3d(),ax.get_ylim3d(),ax.get_zlim3d(),])
origin = np.mean(limits, axis=1)
radius = 0.5 * np.max(np.abs(limits[:, 1] - limits[:, 0]))
_set_axes_radius(ax, origin, radius)
def _set_axes_radius(ax, origin, radius):
x, y, z = origin
ax.set_xlim3d([x - radius, x + radius])
ax.set_ylim3d([y - radius, y + radius])
ax.set_zlim3d([z - radius, z + radius])
ax.set_box_aspect((1, 1, 1))
def set_lim():
global tmax, tmin
tmax = max(np.max(x), np.max(y), np.max(z))
tmin = min(np.min(x), np.min(y), np.min(z))
print(ax.get_xlim3d())
if tmax != tmin:
ax.set_xlim(tmin, tmax)
ax.set_ylim(tmin, tmax)
ax.set_zlim(tmin, tmax)
else:
ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)
ax.set_zlim(-10, 10)
k = 1.0
dt = 0.1
p, = ax.plot(x, y, z)
def fv(v:np.ndarray):
return np.cross(v, np.array([0., 0., 1.]))
def runge_kutta(y:np.ndarray, t:float, f):
k1 = t * f(y)
k2 = t * f(y + 0.5 * k1)
k3 = t * f(y + 0.5 * k2)
k4 = t * f(y + k3)
return y + (k1 + 2 * k2 + 2 * k3 + k4) / 6.
def update(i):
global k, dt, p, x, y, z, v
v = runge_kutta(v, dt, fv)
dx = x[-1] + v[0] * dt
dy = y[-1] + v[1] * dt
dz = z[-1] + v[2] * dt
x = np.append(x, [dx])
y = np.append(y, [dy])
z = np.append(z, [dz])
set_lim()
set_axes_equal(ax)
if i >= 50:x, y, z = x[1:], y[1:], z[1:]
p.set_data_3d(x, y, z)
return (p,)
ani = animation.FuncAnimation(fig2, update, interval=100, frames=None, blit=True)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
when the program runs on its own:
when i move the camera:
Please forgive my poor English. I have been tried to express my problem as clearly as possible. If there's any question about the above, I will try my best to explain it.
Adjusting the camera position manually can make the limits updated successfully, but It cannot update on its own. I just wish the plot line can be at the center of the Axes3D without manually adjusting the camera position.
When you tell matplotlib.animation.FuncAnimation
to blit
it stops updating the axes it seems. Replace your line with this one:
ani = animation.FuncAnimation(fig2, update, interval=100, frames=None)
and it should work as you describe.
Let me know if you have any questions.