簡體   English   中英

通過 Pandas 對 Matplotlib/Seaborn 繪圖進行動畫處理?

[英]Animating Matplotlib/Seaborn plots through Pandas?

我一直在嘗試使用matplotlib.animation為一系列情節制作動畫,但無濟於事。 我的數據當前存儲在 Pandas dataframe 中,我想遍歷一個類別(在本例中為顏色)和 plot 與每種顏色對應的數據如下:

import pandas as pd
import seaborn as sns
import matplotlib.animation as animation

def update_2(i):
    plt.clf()
    fil_test = test[test['color'] == iterations[i]]
    sns.scatterplot(x = 'size',y = 'score',hue = 'shape',ci = None,
                              palette = 'Set1',data = fil_test)
    ax.set_title(r"Score vs. Size: {} Shapes".format(
        iterations[i]),fontsize = 20)
    ax.legend(loc='center left', bbox_to_anchor=(1, 0.5),prop={'size': 12})


test = pd.DataFrame({'color':["red", "blue", "red", 
"yellow",'red','blue','yellow','yellow','red'], 
        'shape': ["sphere", "sphere", "sphere", 
"cube",'cube','cube','cube','sphere','cube'], 
        'score':[1,7,3,8,5,8,6,2,9],
        'size':[2,8,4,7,9,8,3,2,1]})
iterations = test['color'].unique()
i = 0
fig2 = plt.figure(figsize = (8,8))
ax = plt.gca()
plt.axis()
ax.set_xlabel("size",fontsize = 16)
ax.set_ylabel("score",fontsize = 16)
ax.set_xlim(0,10)
ax.set_xlim(0,10)
ax.set_xticks(np.linspace(0,10,6))
ax.set_yticks(np.linspace(0,10,6))
ax.tick_params(axis='both', which='major', labelsize=15)

ani = animation.FuncAnimation(fig2,update_2,frames = len(iterations))
ani.save("test.mp4", dpi=200, fps=1)

但是,此代碼產生了 4 個問題:

  1. 即使我將 animation 保存到ani變量中,它似乎也沒有顯示與每種不同顏色相關的數據。

  2. 標題沒有針對每種顏色適當地顯示/更新。

  3. 調用ax.legend會產生以下錯誤/警告: No handles with labels found to put in legend.

  4. 嘗試保存 animation 會產生以下錯誤: MovieWriterRegistry' object is not an iterator

有人可以解釋為什么當前會出現這些問題,是否有更好的方法來編寫/格式化我的動畫代碼代碼?

看看這段代碼:

import pandas as pd
import seaborn as sns
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np

test = pd.DataFrame({'color': ['red', 'blue', 'red', 'yellow', 'red', 'blue', 'yellow', 'yellow', 'red'],
                     'shape': ['sphere', 'sphere', 'sphere', 'cube', 'cube', 'cube', 'cube', 'sphere', 'cube'],
                     'score': [1, 7, 3, 8, 5, 8, 6, 2, 9],
                     'size': [2, 8, 4, 7, 9, 8, 3, 2, 1]})
iterations = test['color'].unique()

fig, ax = plt.subplots(figsize = (10, 8))
fig.subplots_adjust(top = 0.88, right = 0.85, bottom = 0.11, left = 0.12)

def update(i):
    ax.cla()
    fil_test = test[test['color'] == iterations[i]]
    fil_test = fil_test.sort_values(by = ['shape'])
    sns.scatterplot(x = 'size', y = 'score', hue = 'shape', ci = None, palette = 'Set1', data = fil_test)
    ax.set_title(f'Score vs. Size: {format(iterations[i]):>6} Shapes', fontsize = 20)
    ax.legend(loc = 'center left', bbox_to_anchor = (1, 0.5), prop = {'size': 12})
    ax.set_xlabel('size', fontsize = 16)
    ax.set_ylabel('score', fontsize = 16)
    ax.set_xlim(0, 10)
    ax.set_xlim(0, 10)
    ax.set_xticks(np.linspace(0, 10, 6))
    ax.set_yticks(np.linspace(0, 10, 6))
    ax.tick_params(axis = 'both', which = 'major', labelsize = 15)

ani = animation.FuncAnimation(fig, update, frames = len(iterations))
ani.save('test.mp4', dpi=200, fps=1)

plt.show()

我編輯了一些東西:

  1. 正如@Diziet Asahi已經解釋的那樣,我用plt.clf()替換了 plt.clf ax.cla()以清潔每一幀的軸
  2. update function 中移動了繪圖設置( set_xlabelset_xlimset_xticks等):通過這種方式,每個周期都會調整圖形,因此它在整個 animation 中都是固定的
  3. 如果您不對過濾后的 dataframe fil_test進行排序,則圖例和顏色關聯將相對於 dataframe 中存在的第一個值發生變化。 為了避免這種情況,我添加了fil_test = fil_test.sort_values(by = ['shape']) :這樣, 'cube''sphere'的顏色-圖例關聯在整個 animation 中都是固定的
  4. 添加了fig.subplots_adjust(top = 0.88, right = 0.85, bottom = 0.11, left = 0.12)以便為圖例騰出一些空間
  5. set_title中將 r-string 替換為 f-string 以固定標題的長度以提高其可讀性

結果:

在此處輸入圖像描述

您的問題是您通過調用plt.clf()刪除循環中的ax object 。 相反,您應該調用plt.cla()來清除軸的內容,而不是軸本身。

但是,由於您正在清除軸,它們 go 回到原來的 state,因此您可能還需要在animate ZC1C425268E68385D1AB5074C17A94F14 中重置軸限制和格式

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM