[英]Animating Matplotlib/Seaborn plots through Pandas?
I've been trying to animate a series of plots using matplotlib.animation
to no avail.我一直在尝试使用
matplotlib.animation
为一系列情节制作动画,但无济于事。 My data are currently stored in a Pandas dataframe and I want to iterate through a category (in this case, colors) and plot the data corresponding to each color as the following:我的数据当前存储在 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)
However, 4 issues arise from this code:但是,此代码产生了 4 个问题:
Even though I saved my animation to the ani
variable, it doesn't seem to display the data associated with each different color.即使我将 animation 保存到
ani
变量中,它似乎也没有显示与每种不同颜色相关的数据。
The title doesn't show up/update appropriately for each color.标题没有针对每种颜色适当地显示/更新。
Calling on ax.legend
produces the following error/Warning: No handles with labels found to put in legend.
调用
ax.legend
会产生以下错误/警告: No handles with labels found to put in legend.
Trying to save the animation produces the following Error: MovieWriterRegistry' object is not an iterator
尝试保存 animation 会产生以下错误:
MovieWriterRegistry' object is not an iterator
Could someone explain why these issues currently pop up and is there a better way to write/format my code for animated plots?有人可以解释为什么当前会出现这些问题,是否有更好的方法来编写/格式化我的动画代码代码?
Have a look to this code:看看这段代码:
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()
I edited some things:我编辑了一些东西:
plt.clf()
with ax.cla()
in order to clean the axis at each frameplt.clf()
替换了 plt.clf ax.cla()
以清洁每一帧的轴set_xlabel
, set_xlim
, set_xticks
and so on) inside update
function: in this way the figure is adjusted every cycle so it is fixed throughout the animationupdate
function 中移动了绘图设置( set_xlabel
、 set_xlim
、 set_xticks
等):通过这种方式,每个周期都会调整图形,因此它在整个 animation 中都是固定的fil_test
, the legend and color association will change with respect to the first value present in that dataframe.fil_test
进行排序,则图例和颜色关联将相对于 dataframe 中存在的第一个值发生变化。 In order to avoid that, I added fil_test = fil_test.sort_values(by = ['shape'])
: in this way the color-legend association for 'cube'
and 'sphere'
is fixed throughout the animationfil_test = fil_test.sort_values(by = ['shape'])
:这样, 'cube'
和'sphere'
的颜色-图例关联在整个 animation 中都是固定的fig.subplots_adjust(top = 0.88, right = 0.85, bottom = 0.11, left = 0.12)
in order to make some space for the legendfig.subplots_adjust(top = 0.88, right = 0.85, bottom = 0.11, left = 0.12)
以便为图例腾出一些空间set_title
in order to fix the length of the title so as to improve its readabilityset_title
中将 r-string 替换为 f-string 以固定标题的长度以提高其可读性Result:结果:
Your issue is that you are deleting the ax
object in your loop by calling plt.clf()
.您的问题是您通过调用
plt.clf()
删除循环中的ax
object 。 Instead, you should call plt.cla()
which clear the content of the axes, but not the Axes themselves.相反,您应该调用
plt.cla()
来清除轴的内容,而不是轴本身。
However, since you are clearing the axes, they go back to their original state, so you will probably want to reset the axes limit and formatting in the animate
function as well但是,由于您正在清除轴,它们 go 回到原来的 state,因此您可能还需要在
animate
ZC1C425268E68385D1AB5074C17A94F14 中重置轴限制和格式
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.