在matplotlib动画中更新2D数组作为y数据
我有一组从一个点 X
开始的 N
条随机路径。我有一个滑块,可以改变这个起始点 X
,这样就会生成新的 N
条路径。我想更新这些路径,但 set_ydata
只接受一维数组。目前我每次更新时都在清空坐标轴,然后重新绘制,这样做效率不高。请问在 matplotlib
中有没有什么内置的方法可以做到这一点?
xJ = arange(-10,10,0.1)
psinaive = zeros((xJ.shape[0]))
uapprox = zeros((xJ.shape[0],Nt))
wplot = []
wcondplot = []
for i,x in enumerate(xJ):
WJ = sqrt(dt)*np.random.randn(Ntraj,Nt)
WJ[:,0] = x
WJ = np.cumsum(WJ,1)
wplot.append(WJ)
cond = V(WJ,limits)[0]
wcondplot.append(WJ[cond,:])
wa = 1.0/WJ.shape[0]*exp(-phi(WJ[:,-1],alpha)/lmbda)
psinaive[i] = sum(wa[cond])
uapprox[i,:] = 1.0/psinaive[i]*np.dot(wa[cond],WJ[cond,:]).flatten()
if i % 10 == 0:
print '..%.1f'%x,
J = -lmbda*log(psinaive)
#plot results
ax1=subplot(221)
plot(xJ,J)
plot(xJ,Jl(xJ,ti,tf,alpha,R,v,t1,limits))
title('$J(x,t)$')
plt.axvline(x=-10)
subplot(222)
plot(xJ,uapprox[:,0])
ax3 = subplot(223)
plot(t,wplot[0].T,alpha=0.2)
title('%d paths'%Ntraj)
ylim((-15,15))
ymin,ymax = ylim()
plt.axvline(x=t1, ymin=(d-ymin)/(ymax-ymin), linewidth=2, color='k')
plt.axvline(x=t1, ymin=(b-ymin)/(ymax-ymin), ymax = (c-ymin)/(ymax-ymin), linewidth=2, color='k')
plt.axvline(x=t1, ymax=(a-ymin)/(ymax-ymin), linewidth=2, color='k')
ax4 = subplot(224)
ax4.set_title('No alive paths')
if len(wcondplot[0])>0:
ax4.plot(t,wcondplot[0].T,alpha=0.2)
ax4.set_title('%d alive from %d paths'%(len(wcondplot[0]),Ntraj))
ylim((-15,15))
ymin,ymax = ylim()
plt.axvline(x=t1, ymin=(d-ymin)/(ymax-ymin), linewidth=2, color='k')
plt.axvline(x=t1, ymin=(b-ymin)/(ymax-ymin), ymax = (c-ymin)/(ymax-ymin), linewidth=2, color='k')
plt.axvline(x=t1, ymax=(a-ymin)/(ymax-ymin), linewidth=2, color='k')
subplots_adjust(0.15,0.25)
axsx = axes([0.15,0.1,0.75,0.1])
slx = Slider(axsx,'x',0,len(xJ),0,valfmt='%.0f')
def updatex(val):
x = int(val)
ax1.cla()
ax1.plot(xJ,J)
ax1.plot(xJ,Jl(xJ,ti,tf,alpha,R,v,t1,limits))
ax1.set_title('$J(x,t)$')
ax1.axvline(x=xJ[x])
ax3.cla()
ax3.plot(t,wplot[x].T,alpha=0.2)
ax3.set_title('%d paths'%Ntraj)
ax3.set_ylim((-15,15))
ymin,ymax = ax3.get_ylim()
ax3.axvline(x=t1, ymin=(d-ymin)/(ymax-ymin), linewidth=2, color='k')
ax3.axvline(x=t1, ymin=(b-ymin)/(ymax-ymin), ymax = (c-ymin)/(ymax-ymin), linewidth=2, color='k')
ax3.axvline(x=t1, ymax=(a-ymin)/(ymax-ymin), linewidth=2, color='k')
ax4.cla()
ax4.set_title('No alive paths')
if len(wcondplot[x])>0:
ax4.plot(t,wcondplot[x].T,alpha=0.4)
ax4.set_title('%d alive from %d paths'%(len(wcondplot[x]),Ntraj))
ax4.set_ylim((-15,15))
ymin,ymax = ax4.get_ylim()
ax4.axvline(x=t1, ymin=(d-ymin)/(ymax-ymin), linewidth=2, color='k')
ax4.axvline(x=t1, ymin=(b-ymin)/(ymax-ymin), ymax = (c-ymin)/(ymax-ymin), linewidth=2, color='k')
ax4.axvline(x=t1, ymax=(a-ymin)/(ymax-ymin), linewidth=2, color='k')
draw()
slx.on_changed(updatex)
结果是:
2 个回答
0
试试用 set_data
这个方法,这样你就不用每次都清空再重新绘图了(你已经发现这样做很慢)。下面是一个使用示例:
fig = figure()
ax = fig.add_subplot(111)
p = ax.plot(x, y)
# you do something to your data and want to replot
p.set_data(x, y)
如果你能把你的代码发出来,我们可以帮你找到具体的解决办法。
1
你可以利用这样一个事实:如果你的数组里面有“nans”(也就是缺失值),那么matplotlib会把这些数据分成不同的部分,尽管这个数组是一维的。
x = (np.arange(5 * 4) % 4).reshape(5, 4) * 1.
x[x==3] = np.nan
y = x + (np.arange(5 * 4)/4).reshape(5,4)*1.
line2d = plt.plot(x.flatten(),y.flatten()) [0]
print x,y
> [[ 0., 1., 2., nan],
> [ 0., 1., 2., nan],
> [ 0., 1., 2., nan],
> [ 0., 1., 2., nan],
> [ 0., 1., 2., nan]]
> [[ 0. 1. 2. nan]
> [ 1. 2. 3. nan]
> [ 2. 3. 4. nan]
> [ 3. 4. 5. nan]
> [ 4. 5. 6. nan]]
这样的话,你就可以毫无问题地使用set_data()这个方法,比如:
line2d.set_data(y.flatten()+3)