2017-09-15 50 views
5

一些seaborn方法如JointPlotcreate new figures on each call。这使得不可能创建一个简单的动画,如matplotlib,其中对plt.cla()plt.clf()的迭代调用允许在每次不关闭/打开窗口的情况下更新图形的内容。重绘动画Seaborn数字

我目前看到的唯一的解决办法是:

for t in range(iterations): 
    # .. update your data .. 

    if 'jp' in locals(): 
     plt.close(jp.fig) 

    jp = sns.jointplot(x=data[0], y=data[1]) 
    plt.pause(0.01) 

这工作,因为我们正确的创建一个新之前关闭一个窗口。但当然,这远非理想。

有没有更好的方法?不知何故可以直接在先前生成的Figure对象上完成情节?或者有没有办法阻止这些方法在每次通话中产生新的数字?

回答

4

不幸的是,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

+0

我怀疑这样的事情。我希望这会更直接,但这样做可以很好地完成工作,所以非常感谢。 – runDOSrun

+0

从seaborn的源代码中,你会发现它显然没有被写入可能会记住动画的情节。根据最终目标是什么,当然可以进行一些优化;我正在考虑继承JointGrid的方法,使其更容易被更新,并将其放在一个新的模块中,并在需要时调用它 - 但是如果需要更频繁地执行此类动画,这只会有意义。另外请记住,seaborn大多数是包装matplotlib,这样一个解决方案可能是复制联合图纯粹用matplotlib做的事情。 – ImportanceOfBeingErnest