You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提升Matplotlib绘制的水波干涉动画帧率?

水波干涉可视化动画帧率优化

使用Matplotlib和NumPy实现水波干涉可视化,已完成所有振幅计算,但动画帧率过低,尝试多种优化无效,确认计算过程耗时占比不高,目标将帧率提升至约12fps。相关代码如下:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import matplotlib.animation as animation

"""
 1.parameter setup
"""
L, sep, N, k, cut = 6, 2, 500, 5*2, 0.8 # 0.5倍寬度, 波源與原點距離, 每邊分割數量, 角波數, z軸範圍
fps, frn = 24, 50         # 每秒影格數量, 影格總數
x = np.linspace(-2*L, 2*L, N)   # x axis
y = np.linspace(-L, L, N)   # y axis
X, Y = np.meshgrid(x, y)    # 2D  matrix
j = complex(0, 1)        # 根號 -1

"""
 2.設定計算振幅的函數, 計算每個位置的振幅並存入陣列
"""
# 自訂函式, 計算每個位置對應的振幅
"""
def func(x, y, t):
    r1 = np.sqrt(x**2 + y**2)    # 點波源1
    for i in range(250):
        r1[i] = y[i]+L
    r2 = np.sqrt((x+sep)**2 + y**2)    # 點波源2
    z = np.exp(j*k*r1)/k*3
    for i in range(250, 499):
        z[i] = np.exp(j*k*(r1[249]+r1[i]))/k*3
    
    z_real = np.real(z*np.exp(-j*t))

    return  z_real  # 回傳實部
""" 

def func(x, y, t, n, a, b):
    """
    r0 = np.sqrt((x-6)**2 + y**2) 
    r1 = np.sqrt((x-5)**2 + y**2)
    ...
    r11 = np.sqrt((x+5)**2 + y**2)
    r12 = np.sqrt((x+6)**2 + y**2)
    """
    for i in range(n):
        r = np.sqrt((x-a[i])**2 + (y-b[i])**2)
        if(i == 0):
            z = np.exp(j*k*r)/r
        else:
            z += np.exp(j*k*r)/r

    return np.real(z*np.exp(-j*t))    # 回傳實部


Z = np.zeros((N, N, frn))   # 儲存振幅用的2維陣列
T = np.linspace(0, 2*np.pi, frn)   # 儲存時間用的1維陣列

# user input
n=int(input("輸入波源數量:"))
print('點波源位置輸入格式: x , y')
a=[]
b=[]
for i in range(n):
  temp=input(f"位置{i}:").split(',')
  a.append(int(temp[0]))
  b.append(int(temp[1]))

# 計算每個時刻每個位置對應的振幅, 有加cut效果較佳
for i in range(frn):
    Z[:, :, i] = func(X, Y, T[i], n,a,b).clip(-cut, cut)

"""
 3.繪圖
"""
fig = plt.figure(figsize=(7, 6), dpi=100)   # 開啟繪圖視窗
ax = fig.gca()
ax.set_aspect(1.0)   # 使圖片長寬變成1:1

# 以某個預設的colormap為基底, 修改成對應到 -cut ~ +cut 的colormap
mappable = plt.cm.ScalarMappable(cmap=plt.cm.jet)
mappable.set_array(np.arange(-cut, cut, 0.1))

# 在圖片右側加上color bar, 高度與圖片相同
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(mappable, cax=cax)

# 自訂函式, 先移除前一張圖, 再畫出下一張圖
def update(frame_number):
    plot[0] = ax.contourf(X, Y, Z[:, :, frame_number], cmap=mappable.cmap, norm=mappable.norm)

# t = 0 的圖片
plot = [ax.contourf(X, Y, Z[:, :, 0], cmap=mappable.cmap, norm=mappable.norm)]

# 產生動畫, 目標為繪圖物件fig, 使用自訂函式update更新圖片, 圖片總數為frn, 時間間隔為interal, 單位為ms
ani = animation.FuncAnimation(fig, update, frn, interval=1000/fps)

plt.show()   # 顯示圖片

# ani.save('TwoSourcesInterference2D.gif', writer='imagemagick', fps=fps)   # 儲存圖片
优化方案

帧率低的核心原因是**contourf属于矢量绘图函数,每次重绘都会重新计算等高线并渲染大量矢量图形,开销极大**。针对这个问题,给出以下优化措施:

1. 替换contourf为imshow

imshow是位图渲染函数,适合展示预计算好的二维数组,渲染速度远快于contourf。

2. 优化动画更新逻辑

不再每次创建新的绘图对象,而是直接更新已有对象的数据源,避免重复创建和销毁图形元素的开销。

3. 调整帧率参数

将目标帧率设为12fps,对应interval参数为1000/12(约83ms)。

修改后的完整绘图代码段

"""
 3.繪圖 (優化版)
"""
fig = plt.figure(figsize=(7, 6), dpi=100)
ax = fig.gca()
ax.set_aspect(1.0)

# 設定顏色映射範圍
norm = plt.Normalize(-cut, cut)
mappable = plt.cm.ScalarMappable(cmap=plt.cm.jet, norm=norm)
mappable.set_array([])

# 添加顏色條
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(mappable, cax=cax)

# 使用imshow初始化圖像,設置extent匹配坐標軸
im = ax.imshow(Z[:, :, 0], 
               cmap=plt.cm.jet, 
               norm=norm,
               extent=[x.min(), x.max(), y.min(), y.max()],
               origin='lower')

# 更新函數:僅更換數據源
def update(frame_number):
    im.set_data(Z[:, :, frame_number])
    return [im]

# 生成動畫,設置目標帧率12fps
fps_target = 12
ani = animation.FuncAnimation(fig, update, frames=frn, 
                              interval=1000//fps_target, blit=True)

plt.show()

额外优化建议

  • 若仍觉得帧率不够,可适当降低N(当前为500),减少像素点数量,进一步降低渲染负载。
  • 将用户输入的波源位置转换为NumPy数组,避免函数内循环的列表索引开销:
    # 替换用户输入部分的a、b为numpy数组
    a = np.array(a, dtype=np.float64)
    b = np.array(b, dtype=np.float64)
    

内容的提问来源于stack exchange,提问作者林育正

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:20:40