簡體   English   中英

在 Matplotlib 動畫中更新 Surface_plot 上的 z 數據

[英]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()

請注意,動畫本身的速度由FuncAnimationinterval參數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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM