不幸的是,sns.jointplot
自己创建了一个数字。为了使jointplot动画,可以重新使用这个创建的图形,而不是在每个交互中重新创建一个新图形。
jointplot
内部创建一个JointGrid
,所以直接使用它并单独绘制关节轴和边缘图是有意义的。在动画的每一步中,人们都会更新数据,清除轴并将其设置为与创建网格时相同。不幸的是,这最后一步涉及很多代码行。然后
最后的代码可能看起来像:
import matplotlib.pyplot as plt
import matplotlib.animation
import seaborn as sns
import numpy as np
def get_data(i=0):
x,y = np.random.normal(loc=i,scale=3,size=(2, 260))
return x,y
x,y = get_data()
g = sns.JointGrid(x=x, y=y, size=4)
lim = (-10,10)
def prep_axes(g, xlim, ylim):
g.ax_joint.clear()
g.ax_joint.set_xlim(xlim)
g.ax_joint.set_ylim(ylim)
g.ax_marg_x.clear()
g.ax_marg_x.set_xlim(xlim)
g.ax_marg_y.clear()
g.ax_marg_y.set_ylim(ylim)
plt.setp(g.ax_marg_x.get_xticklabels(), visible=False)
plt.setp(g.ax_marg_y.get_yticklabels(), visible=False)
plt.setp(g.ax_marg_x.yaxis.get_majorticklines(), visible=False)
plt.setp(g.ax_marg_x.yaxis.get_minorticklines(), visible=False)
plt.setp(g.ax_marg_y.xaxis.get_majorticklines(), visible=False)
plt.setp(g.ax_marg_y.xaxis.get_minorticklines(), visible=False)
plt.setp(g.ax_marg_x.get_yticklabels(), visible=False)
plt.setp(g.ax_marg_y.get_xticklabels(), visible=False)
def animate(i):
g.x, g.y = get_data(i)
prep_axes(g, lim, lim)
g.plot_joint(sns.kdeplot, cmap="Purples_d")
g.plot_marginals(sns.kdeplot, color="m", shade=True)
frames=np.sin(np.linspace(0,2*np.pi,17))*5
ani = matplotlib.animation.FuncAnimation(g.fig, animate, frames=frames, repeat=True)
plt.show()
![enter image description here](https://i.stack.imgur.com/uzyHd.gif)
我怀疑这样的事情。我希望这会更直接,但这样做可以很好地完成工作,所以非常感谢。 – runDOSrun
从seaborn的源代码中,你会发现它显然没有被写入可能会记住动画的情节。根据最终目标是什么,当然可以进行一些优化;我正在考虑继承JointGrid的方法,使其更容易被更新,并将其放在一个新的模块中,并在需要时调用它 - 但是如果需要更频繁地执行此类动画,这只会有意义。另外请记住,seaborn大多数是包装matplotlib,这样一个解决方案可能是复制联合图纯粹用matplotlib做的事情。 – ImportanceOfBeingErnest