如何使用第三轴是时间步长的现有 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 图像的最小值和最大值,在本例中为 0
和 1.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()
我为创建 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 图像的最小值和最大值,在本例中为0
和1.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()