我試圖做一個非常簡單的影片并用matplotlib保存,但沒有成功。例如,我想看到一些振蕩的東西:這里是我能做的最好的
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation
#Define x,y vectors and meshgrid with function u on it
x = np.arange(0,10,0.1)
y = np.arange(0,10,0.1)
X,Y = np.meshgrid(x,y)
u = np.sin(X Y)
#Create a figure and an axis object for the surface
#(which by the way is not initialized, because I don't know were to)
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
#Define a kind-of animation function, imitating what I saw many times
def animate(n):
global u
for n in (1,20):
u = np.sin((X Y)*n)
return fig,
#I'm missing many commands, I'm just putting what I know
anim = animation.FuncAnimation(fig,animate)
anim.save('A.mp4',fps=10)
我閱讀了大量在線檔案,包括官方檔案,但我找不到一個表面隨時間演變的明確示例。我還發現很難掌握使用 matplotlib 構建繪圖背后的邏輯(我閱讀了有關圖形、關聯物件、軸、其他物件的資訊……我很困惑),但我也在自學它以備考試和我不是一個真正的技術人員,所以也許這就是我遇到這么多麻煩的原因;從根本上說,如果你回答并能多花兩分鐘更詳細地描述你在做什么,你會讓我很高興。非常感謝您的幫助。
uj5u.com熱心網友回復:
首先,您必須設定曲面的數學域,該域對于每個影片幀都是恒定的,因此您可以在一開始就這樣做:
x = np.arange(0,10,0.1)
y = np.arange(0,10,0.1)
X,Y = np.meshgrid(x,y)
然后就可以初始化圖了:
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
影片的東西來了,你必須定義一個函式來描述一個影片幀和下一個影片幀之間的變化。首先,您必須從圖中清除您在前一幀中已經繪制的內容,這樣您就可以使用ax.cla().
然后是數學部分:你必須定義你的函式以及它如何隨時間變化。請注意,該animate函式帶有一個引數,n在您的情況下,該引數1在每一幀中增加,您可以使用它來描述連續幀之間的變化。例如,如果我寫u = np.sin((X Y) n),那么正弦曲面會在每次迭代中增加它的相位,所以它會“向前移動”;您可以重新定義此方程式,以便通過正確使用n引數來實作您的目標。
然后是時候用 繪制表面了ax.plot_surface(X, Y, u)。這不是強制性的,但我建議修復軸限制,以改進影片,使用ax.set_zlim(-2, 2).
這樣,animate函式定義為:
def animate(n):
ax.cla()
u = np.sin((X Y) n)
ax.plot_surface(X, Y, u)
ax.set_zlim(-2, 2)
return fig,
最后,您必須使用所需的引數設定FuncAnimation物件:
anim = FuncAnimation(fig = fig, func = animate, frames = 10, interval = 1, repeat = False)
完整代碼
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
x = np.arange(0,10,0.1)
y = np.arange(0,10,0.1)
X,Y = np.meshgrid(x,y)
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
def animate(n):
ax.cla()
u = np.sin((X Y) n)
ax.plot_surface(X, Y, u)
ax.set_zlim(-2, 2)
return fig,
anim = FuncAnimation(fig = fig, func = animate, frames = 10, interval = 1, repeat = False)
anim.save('A.mp4',fps=10)

另一個改變表面公式的例子,如果你使用:
u = np.sin(5/2/np.pi*n)*np.sin((X Y))
在animate函式內,則表面相位將保持不變,但順弦表面振幅會發生變化,跟隨其自身為順弦函式,因此您將得到:

uj5u.com熱心網友回復:
這是另一個例子。我從 JavaScript 庫vis3d的圖庫中借來了它,感謝@Zephyr 的回答,我把它變成了 Python。
from math import pi, cos, sin
import numpy as np
import matplotlib.colors as mcolors
from matplotlib import cm
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
x_ = np.linspace(0, 314, 50)
y_ = np.linspace(0, 314, 50)
X, Y = np.meshgrid(x_, y_)
t_ = np.linspace(0, 2*pi, 90)
def f(x, y):
return np.sin(x/50) * np.cos(y/50) * 50 50
def g(x, y, t):
return f(x*cos(t) - y*sin(t), x*sin(t) y*cos(t))
fig = plt.figure()
ax = fig.add_subplot(projection = "3d")
def animate(n):
ax.cla()
Z = g(X, Y, t_[n])
colorfunction = (X**2 Y**2 Z**2)
norm = mcolors.Normalize(colorfunction.min(), colorfunction.max())
ax.plot_surface(
X, Y, Z, rstride = 1, cstride = 1, facecolors=cm.jet(norm(colorfunction))
)
ax.set_zlim(0, 100)
return fig
anim = FuncAnimation(
fig = fig, func = animate, frames = len(t_), interval = 1, repeat = False
)
anim.save("Anim.mp4", fps = 10)

(感謝ezgif.com網站,我將 mp4 轉換為 gif,但 gif 對 SO 來說太大了,所以我用gifsicle壓縮它并且質量有所下降。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/412181.html
標籤:
