一些JointPlot
方法,例如matplotlib
create new figures on each call。这使得无法在plt.cla()
中创建一个简单的动画,其中对plt.clf()
或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
这是有效的,因为我们在创建新窗口之前关闭了上一个窗口。但当然,这远非理想。
有更好的方法吗?可以以某种方式直接在先前生成的{{1}}对象上完成绘图吗?或者有没有办法阻止这些方法在每次调用时生成新数据?
答案 0 :(得分:10)
不幸的是,sns.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()
答案 1 :(得分:3)
使用celluloid
程序包(https://github.com/jwkvam/celluloid),我可以轻松地为海底图制作动画:
import numpy as np
from celluloid import Camera
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
fig = plt.figure()
camera = Camera(fig)
# animation draws one data point at a time
for i in range(0, data.shape[0]):
plot = sns.scatterplot(x=data.x[:i], y=data.y[:i])
camera.snap()
anim = camera.animate(blit=False)
anim.save('animation.mp4')
我确定可以为联合绘图编写类似的代码