python - 通过 Pandas 动画 Matplotlib/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['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 个问题:
即使我将动画保存到
ani
变量中,它似乎也没有显示与每种不同颜色相关的数据。标题没有针对每种颜色适当地显示/更新。
调用
ax.legend
会产生以下错误/警告:No handles with labels found to put in legend.
尝试保存动画会产生以下错误:
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()
我编辑了一些东西:
- 正如@Diziet Asahi已经解释的那样,我替换
plt.clf()
为ax.cla()
以清洁每一帧的轴 - 在函数内部移动绘图设置(
set_xlabel
、set_xlim
等set_xticks
)update
:通过这种方式,每个周期都会调整图形,因此在整个动画过程中它都是固定的 - 如果您不对过滤后的数据框进行排序
fil_test
,则图例和颜色关联将相对于该数据框中存在的第一个值发生变化。为了避免这种情况,我添加了fil_test = fil_test.sort_values(by = ['shape'])
:通过这种方式,颜色-图例关联'cube'
和'sphere'
在整个动画中都是固定的 - 添加
fig.subplots_adjust(top = 0.88, right = 0.85, bottom = 0.11, left = 0.12)
以便为图例腾出一些空间 - 将 r-string 替换为 f-string in
set_title
以固定标题的长度以提高其可读性
结果:
推荐阅读
- python-3.x - 尝试导入时未找到名为 astropy 的模块
- c - 将 .dat 文件中的字符串/行添加到 C 中的哈希表
- python - 如何将 msg 文件转换为 txt 并替换内容?
- c++ - 矢量擦除方法是否需要类具有 = 运算符?
- python - 为逻辑回归转换数据框(一种热编码)
- react-native - 反应原生底部栏高度
- typescript - 自定义对象返回错误:类型“void”.ts(2339) 上不存在属性“forEach”
- sql - 我想打印不包括空值的值。我应该怎么办?
- python - Python语音识别错误错误请求
- javascript - 如何创建检查方法来检查用户输入是否与提供的 ID 匹配?