如何使用第三轴是时间步长的现有 3D 数组为 python pcolormesh 设置动画?

How can I animate a python pcolormesh using an existing 3D array where the third axis is the time steps?

我为创建 x、y 和 t 的 3D 阵列的 2D 扩散方程创建了 pcolormesh。特定 t 的静态 2D 图很简单。我怎样才能在所有时间步长上对其进行动画处理?

我使用以下方法创建 3D 阵列:

set array for x and y
grid_size = 100
t_iter = 1000

D = .01
length = 1.0
tmax = 1.0

dx = dy = length/grid_size
dt = tmax/t_iter

rho = np.zeros((grid_size, grid_size, t_iter))
#rho[:] = 1.2
rho[grid_size//2, grid_size//2, 0] = 1.2  # set the initial configuration

for n in range(t_iter-1):
    for j in range(grid_size-1):
        for i in range(grid_size-1):
            pxx = rho[i+1,j,n] + rho[i-1,j,n] - 2*rho[i,j,n]
            pyy = rho[i,j+1,n] + rho[i,j-1,n] - 2*rho[i,j,n]
            rho[i,j,n+1] = D*dt*(pxx/dx**2+pyy/dy**2)

我可以使用 pcolormesh(没有标签和东西)为特定的 t 值绘制数据:

plt.pcolormesh(rho[:,:,500])

我试过了,但它没有“激活”任何东西。我错过了什么?

from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()

mesh = ax.pcolormesh(rho[:,:,0])

def animate(i):
    ax.pcolormesh(rho[:,:,i])
    
anim = FuncAnimation(fig, animate, interval=10, frames=t_iter-1, repeat=False)

plt.draw()
plt.show()

三处错误:

  • animate() 中,应更新网格。 mesh.set_array() 设置新值。由于内部数据结构需要一个一维数组,二维数组应该“搞定”:mesh.set_array(rho[:, :, i].ravel()).
  • animate() 应该 return 已更改元素的列表。 return mesh, 中的尾随逗号是 Python 制作仅包含一个元素的“元组”的方法。
  • 这里最棘手的问题是最好所有图像都使用相同的颜色映射。 vmin 告诉哪个值映射到“最低”颜色(默认 viridis 映射中的深紫色),而 vmax 对应于“最高”颜色的值(viridis 中的黄色)。如果它们是明确设置的,matplotlib 会将它们计算为 first 图像的最小值和最大值,在本例中为 01.2。这些值不适用于其他图像。通常,整体最小值和最大值给出合适的值。但是,在这种情况下,图像的“有趣”部分在更窄的范围内。我尝试使用第 1 个和第 99 个百分位数,它们似乎运行良好,但您可能需要调整这些值。

更新后的代码:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np

grid_size = 100
t_iter = 1000

D = .01
length = 1.0
tmax = 1.0

dx = dy = length / grid_size
dt = tmax / t_iter

rho = np.zeros((grid_size, grid_size, t_iter))
# rho[:] = 1.2
rho[grid_size // 2, grid_size // 2, 0] = 1.2  # set the initial configuration

for n in range(t_iter - 1):
    for j in range(grid_size - 1):
        for i in range(grid_size - 1):
            pxx = rho[i + 1, j, n] + rho[i - 1, j, n] - 2 * rho[i, j, n]
            pyy = rho[i, j + 1, n] + rho[i, j - 1, n] - 2 * rho[i, j, n]
            rho[i, j, n + 1] = D * dt * (pxx / dx ** 2 + pyy / dy ** 2)

fig, ax = plt.subplots()

mesh = ax.pcolormesh(rho[:, :, 0], vmin=np.percentile(rho.ravel(), 1), vmax=np.percentile(rho.ravel(), 99))

def animate(i):
    mesh.set_array(rho[:, :, i].ravel())
    return mesh,

anim = FuncAnimation(fig, animate, interval=10, frames=t_iter, repeat=False)
plt.show()