python - 具有 pcolormesh 和轮廓的 Matplotlib 动画

标签 python python-2.7 animation matplotlib

我正在使用时空数组,我想导出结果以用于可视化目的。我可以以一定的时间间隔提取图像来显示空间变化。现在,我想粘合这些图像以获得动画。

使用下面的代码,我有两个问题:

  1. 我获得的动画仅显示最后一个图像(因此没有动画!)
  2. 轮廓(当前已注释)绘制在上一张图像的顶部。

代码在原始版本的基础上进行了简化,但仍然很长,抱歉!我插入了注释来帮助理解这些步骤。

我正在 32 位 Windows 7 计算机上使用 Python 2.7.2、matplotlib 1.2.1。

提前致谢!

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import tempfile, os

duration = 5
timesteps = np.arange(0, duration, 1)
ncol = 6
nrow = 13
nlay = 2
cmap = plt.cm.gist_rainbow_r
CBlabel = 'values ([-])'
plt_title = 'VALUES'

# create output folder
ws = os.path.join(tempfile.gettempdir(), "__ani")
f = 0
if os.path.exists(ws):
    ws1 = ws
    while os.path.exists(ws1):
        ws1 = '%s%d' % (ws, f)
        f +=1
    os.makedirs(ws1)
    ws = ws1
    del ws1
else:
    os.makedirs(ws)

# create  coordinate arrays
x = np.arange(0.5, ncol+1.5, 1)
y = np.arange(0.5, nrow+1.5, 1)
xg,yg = np.meshgrid(x,y)

x = np.arange(1, ncol+1, 1)
y = np.arange(1, nrow+1, 1)
xg1,yg1 = np.meshgrid(x,y)

# create values to be plotted
V = np.zeros([duration,nrow,ncol,nlay], dtype = float)
for d in timesteps:
    for L in range(nlay):
        V[d,:,:,L] = ((np.random.rand(nrow, ncol)+0.5)*xg1+(np.random.rand(nrow, ncol)+0.5)*yg1)/(1.0+2.0*L)
Vmax = np.max(V)
Vmin = np.min(V)
ticks = np.linspace(Vmin,Vmax,5)

# plot initialization
ax= []
fig = plt.figure(num=None, figsize=(11.7, 8.27), dpi=30)
figtitle = fig.suptitle('')
for L in range(nlay):
    ax.append(fig.add_subplot(1,nlay,L+1, axisbg = 'silver'))
    ax[L].xaxis.set_ticks(np.arange(0,ncol+1,1))
    ax[L].yaxis.set_ticks(np.arange(0,nrow+1,1))
    plt.setp(ax[L].get_xticklabels(), fontsize=8)
    plt.setp(ax[L].get_yticklabels(), fontsize=8)
    plt.ylabel('row i', fontsize=10)
    plt.xlabel('col j', fontsize=10)
    ax[L].set_title('layer ' + str(L+1), fontsize = 10)

# plot sequences of grids
ims = []
for i, day in enumerate(timesteps):
    ims.append([])
    figtitle.set_text(plt_title + '\ntime step %s' % (day))
    plt.draw()
    for L in range(nlay):
        Vtmp = V[day,:,:,L]
        ims[i].append(ax[L].pcolormesh(xg, yg, Vtmp, cmap = cmap, vmin = Vmin, vmax = Vmax))
        # plot contours with labels
        #ims[i].append(ax[L].contour(xg1, yg1[::-1], Vtmp[::-1], ticks, colors = 'gray'))
        #ax[L].clabel(ims[i][4*i+L+1], inline=1, fontsize = 6, fmt='%2.2f', colors = 'gray')
        del Vtmp
        # modify axes range
        ax[L].set_ylim(bottom = np.max(yg1), top = np.min(yg1))
        ax[L].axis('scaled')
    # create color bar
    cax = fig.add_axes([0.035, 0.125, 0.025, 0.75])
    CB = fig.colorbar(ims[0][0], extend='both', ticks = ticks, format = '%2.2f', cax = cax,  orientation = 'vertical')
    CB.set_label(CBlabel, fontsize = 12)
    cax.yaxis.set_label_position('left')
    plt.setp(CB.ax.get_yticklabels(), fontsize = 7)
    # save image
    plt_export_fn = os.path.join(ws, '_plt_%s_timestep%05d.png' % (plt_title, day))
    plt.savefig(plt_export_fn)

# save animation
ani = animation.ArtistAnimation(fig, ims, interval=1000*(timesteps[1]-timesteps[0]), repeat_delay=500, blit=False)
ani.save(os.path.join(ws, '_plt_%s_mov.mp4' % plt_title))
plt.close('all')

print "Done!\nCheck output in:\n%s" % ws

最佳答案

外部工具的命令行似乎有问题。 转到 png 文件所在的目录并键入以下命令:

ffmpeg -r 10 -i _plt_VALUES_timestep%05d.png -s:v 1280x720 -c:v libx264 -profile:v high -crf 23 -pix_fmt yuv420p -r 30 movie.mp4

应生成一个包含五个动画时间步长的文件 movie.mp4

关于python - 具有 pcolormesh 和轮廓的 Matplotlib 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16803229/

相关文章:

python - 为什么我的 Python 函数中的坐标变量没有递增和递减?

python - Python 中的插入排序不起作用

python - 如何通过在 Python 中调用相同的字典值每次都返回新的对象?

python-2.7 - Python 2.7 pip install lxml UnicodeDecodeError

javascript - jQuery animate() - 调用非常慢

python - Pandas 将数据框展平为单列

python - 在 Linux 上开发 HDMI 端口

python-2.7 - 对 Tkinter bind_class 感到困惑

html - 跳动的心 CSS 动画

jQuery 动画。动画 div 总是在最上面。我需要它在另一个 div 后面