1. 程式人生 > >Matplotlib藉助ImageMagick或ffmpeg生成動圖(.gif)或視訊可能遇到的問題和解決方案

Matplotlib藉助ImageMagick或ffmpeg生成動圖(.gif)或視訊可能遇到的問題和解決方案

準備工作

首先保證要安裝matplotlib。假如按照以下流程並且在網上尋求解答依然沒能成功執行,可能在於matplotlib版本太舊導致。

更新使用pip:pip install -U matplotlib或者使用conda:conda update conda或者conda update matplotlib.

生成動圖(.gif)

ImageMagick

  1. 安裝後,安裝選項中會有安裝ffmpeg等選項,建議所有選項都勾選。其中ffmpeg可以用於之後生成.mp4等,也可以單獨下載和使用。

  2. 之後檢查安裝路徑下是否有convert.exe,有的話就大體沒問題,否則重新選擇正確的版本下載。

  3. 安裝正確後,將安裝檔案所在路徑加入到環境變數中(通常安裝的時候就新增到環境變數中了)。

    不推薦但也是解決方法:假如不想新增到環境變數中或者忘了,則可以參考這裡的做法,在notebook或者IDE中打印出matplotlib.matplotlib_fname()所在位置,並修改xxx\Lib\site-packages\matplotlib\mpl-data\matplotlibrc文字檔案,將其中animation.convert_path:解註釋,並在之後新增convert.exe路徑,例如animation.convert_path: '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe"'

    .

  4. 對於Plot的動態效果顯示,若是在PyCharm等IDE中,開啟終端或者使用命令列模式(而不是直接點選run),才可以顯示動畫。若是在notebook中,可以在導包語句加入一條%matplotlib notebook,則可以在當前cell執行之後檢視動畫效果;若想在cell之外即圖表視窗中顯示,請將%matplotlib notebook改為%matplotlib後面什麼都不接(表示使用預設影象引擎),然後重啟當前的kernel,重新執行此cell即可。
  5. 動畫檢視,對於IDE如PyCharm,使用命令列模式開啟終端運行當前程式,即可檢視動畫效果,否則是單張圖片。這裡給出一個簡單的樣例:
import
numpy as np import matplotlib.pyplot as plt from matplotlib import animation fig, ax = plt.subplots(dpi=72, figsize=(8,6)) x = np.arange(-2*np.pi, 2*np.pi, 0.01) y = np.sin(x) line, = ax.plot(x, y) def init(): line.set_ydata(np.sin(x)) return line def animate(i): line.set_ydata(np.sin(x+i/10.0)) return line animation = animation.FuncAnimation(fig=fig, func=animate, frames=100, # total 100 frames init_func=init, interval=20,# 20 frames per second blit=False) animation.save('sinx.gif', writer='imagemagick') plt.show()

若能生成如下圖所示的動圖則為正常,若不能請仔細核對上面的幾點。
Gif

生成視訊(.mp4等)

matplotlib生成的圖表同樣可以轉換為視訊。使用的是ffmpeg,可以到官網下載對應的版本,其中windows先點選Download然後點選頁面中下的build去選擇你電腦的版本,預設選擇static就行了。

由於速度超慢,所以這裡下載後我把它們放在了百度網盤 密碼:jq86了,資料夾中還有上文的ImageMagick,需要者自取。

下載後將安裝後文件路徑新增到系統環境變數中,cmd中輸入ffmpeg -version若顯示出對應的版本則表示安裝無誤。

若安裝了ImageMagick則生成視訊只需要將上面程式碼的.gif改成.mp4即可,然後以終端/命令列模式執行。

若是單獨安裝的ffmpeg,則將animation.save('sinx.gif', writer='imagemagick')改為animation.save('sinx.mp4', writer='ffmpeg')或者animation.save('sinx.mp4')預設ffmpeg就能生成.mp4動態圖表,同樣然後以終端/命令列模式執行。

另外提供官方示例程式碼:

import numpy as np
import matplotlib
# matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.animation as animation


def update_line(num, data, line):
    line.set_data(data[..., :num])
    return line,

# Set up formatting for the movie files
Writer = animation.writers['ffmpeg']
writer = Writer(fps=15, metadata=dict(artist='Me'), bitrate=1800)


fig1 = plt.figure()

data = np.random.rand(2, 25)
l, = plt.plot([], [], 'r-')
plt.xlim(0, 1)
plt.ylim(0, 1)
plt.xlabel('x')
plt.title('test')
line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l),
                                   interval=50, blit=True)
line_ani.save('lines.mp4', writer=writer)

fig2 = plt.figure()

x = np.arange(-9, 10)
y = np.arange(-9, 10).reshape(-1, 1)
base = np.hypot(x, y)
ims = []
for add in np.arange(15):
    ims.append((plt.pcolor(x, y, base + add, norm=plt.Normalize(0, 30)),))

im_ani = animation.ArtistAnimation(fig2, ims, interval=50, repeat_delay=3000,
                                   blit=True)
im_ani.save('im.mp4', writer=writer)

祝各位玩得愉快。
視訊效果