Python 通过熊猫制作Matplotlib/海洋出生情节动画?

Python 通过熊猫制作Matplotlib/海洋出生情节动画?,python,matplotlib,animation,plot,seaborn,Python,Matplotlib,Animation,Plot,Seaborn,我一直在尝试使用matplotlib.animation制作一系列绘图的动画,但没有效果。我的数据当前存储在Pandas数据框中,我希望遍历一个类别(在本例中为颜色),并按照以下方式绘制与每种颜色对应的数据: import pandas as pd import seaborn as sns import matplotlib.animation as animation def update_2(i): plt.clf() fil_test = test[test['colo

我一直在尝试使用
matplotlib.animation
制作一系列绘图的动画,但没有效果。我的数据当前存储在Pandas数据框中,我希望遍历一个类别(在本例中为颜色),并按照以下方式绘制与每种颜色对应的数据:

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个问题:

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()
  • 即使我将动画保存到
    ani
    变量中,它似乎也不会显示与每种不同颜色相关的数据

  • 标题没有针对每种颜色适当显示/更新

  • 调用
    ax.legend
    会产生以下错误/警告:
    找不到可放入legend中的标签句柄。

  • 尝试保存动画会产生以下错误:
    MovieWriterRegistry'对象不是迭代器


  • 有人能解释一下为什么会出现这些问题,有没有更好的方法来编写/格式化动画绘图的代码?

    您的问题是,您正在通过调用
    plt.clf()
    删除循环中的
    ax
    对象。相反,您应该调用
    plt.cla()
    ,清除轴的内容,而不是轴本身


    但是,由于您正在清除轴,因此它们会返回到原始状态,因此您可能还需要在
    动画
    功能中重置轴限制和格式

    查看以下代码:

    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()
    
    我编辑了一些东西:

  • 如前所述,我将
    plt.clf()
    替换为
    ax.cla()
    ,以便在每个帧处清洁轴
  • 更新
    功能中移动打印设置(
    设置标签
    设置标签
    设置标签
    等等):这样,图形在每个周期都会调整,因此在整个动画中都是固定的
  • 如果未对过滤后的数据框进行排序,则图例和颜色关联将相对于该数据框中的第一个值发生变化。为了避免这种情况,我添加了
    fil\u test=fil\u test.sort\u值(按=['shape'])
    :这样,在整个动画中,
    'cube'
    'sphere'
    的颜色图例关联是固定的
  • 添加了
    图子图\u调整(顶部=0.88,右侧=0.85,底部=0.11,左侧=0.12)
    ,以便为图例留出一些空间
  • set_title
    中用f-string替换r-string,以固定标题的长度,从而提高其可读性
  • 结果:

    似乎ax.cla()是实现此功能的关键!我还想做一些额外的定制,但我可以自己做。谢谢你的帮助!