我有一個來自庫的繪圖函式,它接受一個陣列并從中生成一個熱圖(為了 MWE,我將在此處使用 plt.imshow)。該函式不回傳任何內容:它只是呼叫 plt.show():
import matplotlib.pyplot as plt
import numpy as np
# Complicated function from a library which I technically could but should not modify
# simplified for MWE
def heatmap(arr):
fig, ax = plt.subplots()
_ = ax.imshow(arr)
fig.show()
如果我在回圈中呼叫這個函式,那么我會得到多個數字。
for i in range(100):
arr = np.random.rand(10,10)
heatmap(arr)
我想收集這些數字并在最后為它們制作影片,例如:
plots = []
for i in range(100):
arr = np.random.rand(10,10)
heatmap(arr)
plots.append(plt.gca()) # what should this actually look like?
# wish this existed
plt.animate(plots) # ???
我確實可以訪問代碼,heatmap因此我可以在技術上對其進行更改以回傳圖形和軸,但我想找到一個簡單的解決方案,即使我無法訪問繪圖代碼也能正常作業。
matplotlib 有可能嗎?我在檔案中看到的所有示例都表明我必須更新該圖,而不是收集許多不同的圖。
uj5u.com熱心網友回復:
根據評論,我找到了一個可行的解決方案,可以收集回圈生成的繪圖,而無需訪問繪圖功能,并將它們保存到影片中。
我使用的原始回圈如下:
for i in range(100):
arr = np.random.rand(10,10)
heatmap(arr)
我將首先給出解決方案,然后逐步解釋邏輯。
最終解決方案
plots = []
for i in range(100):
arr = np.random.rand(10,10)
heatmap(arr)
if i==0:
fig, ax = plt.gcf(), plt.gca()
else:
dummy_fig, ax = plt.gcf(), plt.gca()
ax.set(animated=True)
ax.remove()
ax.figure = fig
fig.add_axes(ax)
plt.close(dummy_fig)
plots.append([ax])
ani = animation.ArtistAnimation(fig, plots, interval=50, repeat_delay=200)
ani.save("video.mp4")
分步說明
為了保存繪圖并為以后設定影片,我必須進行以下修改:
- 獲取圖中生成的圖形和軸的句柄:
for i in range(100):
arr = np.random.rand(10,10)
heatmap(arr)
fig, ax = plt.gcf(), plt.gca() # add this
- 使用第一個圖形作為所有未來軸的繪圖畫布:
for i in range(100):
arr = np.random.rand(10,10)
heatmap(arr)
if i==0: # fig is the one we'll use for our animation canvas.
fig, ax = plt.gcf(), plt.gca()
else:
dummy_fig, ax = plt.gcf(), plt.gca() # we will ignore dummy_fig
plt.close(dummy_fig)
- 在關閉其他圖形之前,將它們的軸移動到我們的主畫布
for i in range(100):
arr = np.random.rand(10,10)
heatmap(arr)
if i==0:
fig, ax = plt.gcf(), plt.gca()
else:
dummy_fig, ax = plt.gcf(), plt.gca()
ax.remove() # remove ax from dummy_fig
ax.figure = fig # now assign it to our canvas fig
fig.add_axes(ax) # also patch the fig axes to know about it
plt.close(dummy_fig)
- 將軸設定為影片(但似乎并非絕對必要)
```python
for i in range(100):
arr = np.random.rand(10,10)
heatmap(arr)
if i==0:
fig, ax = plt.gcf(), plt.gca()
else:
dummy_fig, ax = plt.gcf(), plt.gca()
ax.set(animated=True) # from plt example, but doesn't seem needed
# we could however add info to each plot here, e.g.
# ax.set(xlabel=f"image {i}") # this could be done in i ==0 cond. too.
ax.remove()
ax.figure = fig
fig.add_axes(ax)
plt.close(dummy_fig)
- 現在只需將所有這些軸收集到一個串列中,然后繪制它們。
plots = []
for i in range(100):
arr = np.random.rand(10,10)
heatmap(arr)
if i==0:
fig, ax = plt.gcf(), plt.gca()
else:
dummy_fig, ax = plt.gcf(), plt.gca()
ax.set(animated=True)
ax.remove()
ax.figure = fig
fig.add_axes(ax)
plt.close(dummy_fig)
plots.append([ax])
ani = animation.ArtistAnimation(fig, plots, interval=50, repeat_delay=200)
ani.save("video.mp4")
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/493206.html
標籤:Python matplotlib 动画
上一篇:如何為容器的大小設定影片,因為其中的內容在Flutter中發生變化?
下一篇:來自預制件的物件影片存在問題
