[英]Updating z data on a surface_plot in Matplotlib animation
我希望在曲面圖中創建動畫。 動畫具有固定的 x 和 y 數據(每個維度中為 1 到 64),並通過 np 數組讀取 z 信息。 代碼的大綱是這樣的:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def update_plot(frame_number, zarray, plot):
#plot.set_3d_properties(zarray[:,:,frame_number])
ax.collections.clear()
plot = ax.plot_surface(x, y, zarray[:,:,frame_number], color='0.75')
fig = plt.figure()
ax = plt.add_subplot(111, projection='3d')
N = 64
x = np.arange(N+1)
y = np.arange(N+1)
x, y = np.meshgrid(x, y)
zarray = np.zeros((N+1, N+1, nmax+1))
for i in range(nmax):
#Generate the data in array z
#store data into zarray
#zarray[:,:,i] = np.copy(z)
plot = ax.plot_surface(x, y, zarray[:,:,0], color='0.75')
animate = animation.FuncAnimation(fig, update_plot, 25, fargs=(zarray, plot))
plt.show()
因此代碼生成 z 數據並更新 FuncAnimation 中的繪圖。 但是,這非常慢,我懷疑這是由於每個循環都重新繪制了情節。
我試過這個功能
ax.set_3d_properties(zarray[:,:,frame_number])
但它出現了一個錯誤
AttributeError: 'Axes3DSubplot' object has no attribute 'set_3d_properties'
如何僅在 z 方向更新數據而不重新繪制整個圖? (或以其他方式增加繪圖程序的幀率)
調用plot_surface
時,表面下會發生很多事情。 在嘗試將新數據設置到 Poly3DCollection 時,您需要復制所有這些數據。
這實際上可能是可能的,並且可能還有一種方法可以比 matplotlib 代碼更有效地做到這一點。 然后的想法是從網格點計算所有頂點並將它們直接提供給Poly3DCollection._vec
。
但是,動畫的速度主要取決於執行 3D->2D 投影所需的時間和繪制實際繪圖的時間。 因此,當涉及到繪圖速度時,上述內容無濟於事。
最后,您可能只是堅持當前的動畫表面方式,即刪除之前的繪圖並繪制新的繪圖。 但是,在表面上使用較少的點會顯着提高速度。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation
def update_plot(frame_number, zarray, plot):
plot[0].remove()
plot[0] = ax.plot_surface(x, y, zarray[:,:,frame_number], cmap="magma")
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
N = 14
nmax=20
x = np.linspace(-4,4,N+1)
x, y = np.meshgrid(x, x)
zarray = np.zeros((N+1, N+1, nmax))
f = lambda x,y,sig : 1/np.sqrt(sig)*np.exp(-(x**2+y**2)/sig**2)
for i in range(nmax):
zarray[:,:,i] = f(x,y,1.5+np.sin(i*2*np.pi/nmax))
plot = [ax.plot_surface(x, y, zarray[:,:,0], color='0.75', rstride=1, cstride=1)]
ax.set_zlim(0,1.5)
animate = animation.FuncAnimation(fig, update_plot, nmax, fargs=(zarray, plot))
plt.show()
請注意,動畫本身的速度由FuncAnimation
的interval
參數FuncAnimation
。 在上面它沒有指定,因此默認為 200 毫秒。 根據數據,您仍然可以在遇到滯后幀問題之前降低該值,例如嘗試 40 毫秒並根據您的需要進行調整。
animate = animation.FuncAnimation(fig, update_plot, ..., interval=40, ...)
set_3d_properties()
是Poly3DCollection
類的函數,而不是Axes3DSubplot
。
你應該跑
plot.set_3d_properties(zarray[:,:,frame_number])
正如你在更新函數中評論的那樣,而不是
ax.set_3d_properties(zarray[:,:,frame_number])
我不知道這是否能解決您的問題,但我不確定,因為函數set_3d_properties
沒有附加文檔。 我想知道您是否最好嘗試使用plot.set_verts()
代替。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.