Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用固定数据框进行动态matplotlib打印?_Python_Pandas_Matplotlib_Animation - Fatal编程技术网

Python 如何使用固定数据框进行动态matplotlib打印?

Python 如何使用固定数据框进行动态matplotlib打印?,python,pandas,matplotlib,animation,Python,Pandas,Matplotlib,Animation,我有一个名为benchmark\u returns和strategy\u returns的数据框架。两者的时间跨度相同。我想找到一种方法,以一种很好的动画风格来绘制数据点,以便它显示逐渐加载的所有点。我知道有一个matplotlib.animation.FuncAnimation(),但是这通常只用于实时更新csv文件等,但在我的情况下,我知道我要使用的所有数据 我也尝试过使用粗糙的plt.pause(0.01)方法,但是随着绘制点数的增加,速度会急剧减慢 这是到目前为止我的代码 x = ben

我有一个名为
benchmark\u returns
strategy\u returns
的数据框架。两者的时间跨度相同。我想找到一种方法,以一种很好的动画风格来绘制数据点,以便它显示逐渐加载的所有点。我知道有一个
matplotlib.animation.FuncAnimation()
,但是这通常只用于实时更新csv文件等,但在我的情况下,我知道我要使用的所有数据

我也尝试过使用粗糙的
plt.pause(0.01)
方法,但是随着绘制点数的增加,速度会急剧减慢

这是到目前为止我的代码

x = benchmark_returns.index
y = benchmark_returns['Crypto 30'] 
y2 = benchmark_returns['Dow Jones 30']
y3 = benchmark_returns['NASDAQ'] 
y4 = benchmark_returns['S&P 500']


fig, ax = plt.subplots()
line, = ax.plot(x, y, color='k')
line2, = ax.plot(x, y2, color = 'b')
line3, = ax.plot(x, y3, color = 'r')
line4, = ax.plot(x, y4, color = 'g')

def update(num, x, y, y2, y3, y4, line): 
    line.set_data(x[:num], y[:num])
    line2.set_data(x[:num], y2[:num])
    line3.set_data(x[:num], y3[:num])
    line4.set_data(x[:num], y4[:num])

    return line, line2, line3, line4,

ani = animation.FuncAnimation(fig, update, fargs=[x, y, y2, y3, y4, line], 
                              interval = 1, blit = True)
plt.show()

您可以将数据更新到line元素中,如下所示:

fig = plt.figure()
ax = fig.add_subplot(111)
liner, = ax.plot()
plt.ion()
plt.show()
for i in range(len(benchmark_returns.values)):
    liner.set_ydata(benchmark_returns['Crypto 30'][:i])
    liner.set_xdata(benchmark_returns.index[:i])
    plt.pause(0.01)
你可以试试。它的操作类似于
FuncAnimation
,因为您可以指定帧间隔、循环行为等,但所有打印都是在动画步骤之前一次完成的。这里有一个例子

导入matplotlib.pyplot作为plt
作为pd进口熊猫
将numpy作为np导入
从matplotlib.animation导入ArtistAnimation
n=150
x=np.linspace(0,np.pi*4,n)
df=pd.DataFrame({'cos(x)':np.cos(x),
“sin(x)”:名词sin(x),
“tan(x)”:名词tan(x),
“sin(cos(x))”:np.sin(np.cos(x))})
图,axs=plt.子批次(nrows=2,ncols=2,figsize=(10,10))
行=[]
艺术家=[]]
对于ax,zip中的列(axs.flatte(),df.columns.values):
行追加(ax.plot(df[col])[0])
artists.append(lines.copy())
动画=艺术形象(图,艺术家,间隔=500,重复时间=1000)

这里的缺点是,每个艺术家要么被绘制,要么不被绘制,也就是说,如果不进行剪裁,就不能只绘制
Line2D
对象的一部分。如果这与您的用例不兼容,那么您可以尝试将
FuncAnimation
blit=True
一起使用,并将每次要绘制的数据分块,以及使用
set_data()
而不是在每次迭代时清除和重新绘制。使用上述相同数据的示例如下:

导入matplotlib.pyplot作为plt
作为pd进口熊猫
将numpy作为np导入
从matplotlib.animation导入FuncAnimation
n=500
nf=100
x=np.linspace(0,np.pi*4,n)
df=pd.DataFrame({'cos(x)':np.cos(x),
“sin(x)”:名词sin(x),
“tan(x)”:名词tan(x),
“sin(cos(x))”:np.sin(np.cos(x))})
图,axs=plt.子批次(2,2,figsize=(5,5),dpi=50)
行=[]
对于ax,zip中的列(axs.flatte(),df.columns):
line.append(ax.plot([],lw=0.5)[0])
ax.set_xlim(x[0]-x[-1]*0.05,x[-1]*1.05)
ax.set_ylim([min(df[col].值)*1.05,max(df[col].值)*1.05])
最大勾选参数(labelbottom=False,bottom=False,left=False,labelleft=False)
plt.子批次调整(hspace=0,wspace=0,左=0.02,右=0.98,底部=0.02,顶部=0.98)
利润率(1,1)
c=int(n/nf)
定义动画(i):
如果(i!=nf-1):
对于行,zip中的列(行,df.列):
line.set_数据(x[:(i+1)*c],df[col]。值[:(i+1)*c])
其他:
对于行,zip中的列(行,df.列):
line.set_数据(x,df[col].值)
回程线
anim=FuncAnimation(图,动画,间隔=2000/nf,帧=nf,blit=True)


编辑 作为对评论的回应,以下是使用问题中更新的代码实现分块方案:

x=benchmark\u returns.index
y=基准_返回值['Crypto 30']
y2=基准_收益率['Dow Jones 30']
y3=基准_收益率['NASDAQ']
y4=基准_收益率['S&P500']
直线,=ax.plot(x,y,color='k')
第2行,=ax.plot(x,y2,颜色='b')
第3行,=ax.plot(x,y3,颜色='r')
第4行,=ax.plot(x,y4,颜色='g')
n=len(x)#总行数
c=50#块大小
def更新(num):
如果num*c
或者,更简洁地说

cols=benchmark\u返回.columns.values
#或者,仅用于列的子集
#cols=[‘加密30’、‘道琼斯30’、‘纳斯达克’、‘标准普尔500’]
颜色=['k','b','r','g']
行=[]
对于c,拉链中的颜色(颜色):
line.append(ax.plot(benchmark\u returns.index,benchmark\u returns[col].values,c=c)[0])
n=len(基准返回指数)
c=50#块大小
def更新(num):
如果num*c

如果您需要它在特定时间后停止更新,只需在
FuncAnimation()

中设置
frames
参数和
repeat=False
,我得到了一个``File“results.py”,第91行,在liner中,=ax.plot()value错误:没有足够的值来解包(预期值为1,实际值为0)```error insteadI设法修复了错误,但运行时非常糟糕,有没有关于如何修复错误的提示?如果您可以使用NumPy数组作为输入而不是pandas系列,您可以看到运行时的潜在改进。您可能会发现这非常有帮助。还有其他比
matplotlib
更快的方法。我已经尝试过了,但是运行时不是最好的。看起来,随着数据规模的扩大,fps灾难性地下降。@HamishGibson这在某种程度上是不可避免的,当然有办法减轻它(使用
blit
,使用
set_data()
,而不是清除和重新填充等),但在一定规模下,它仍然成为硬件问题。保证FPS不受数据大小影响的唯一真正方法是保存动画而不是实时显示