2015-08-25 109 views
1

我试图在matplotlib中获得实时频谱分析器类型阴谋。我有一些代码工作(与在计算器上其他职位帮助)如下:matplotlib中的实时阴谋 - python

import time 
import numpy as np 
import matplotlib.pyplot as plt 

plt.axis([0, 1000, 0, 1]) 
plt.ion() 
plt.show() 

i=0 
np.zeros([1,500],'float') 
lines=plt.plot(y[0]) 

while 1: 
    i=i+1 
    lines.pop(0).remove() 
    y = np.random.rand(1,100) 
    lines=plt.plot(y[0]) 
    plt.draw() 

代码工作,我得到我想要的东西,但有一个严重的问题。情节窗口会在一段时间后冻结。我知道该程序仍在运行,通过检查变量(我在Anaconda/Spyder中运行代码,所以我可以看到变量)。然而,绘图窗口会显示“无响应”,如果我通过ctrl + c终止Spyder中的python程序,绘图窗口会恢复生命并显示最新的绘图。

因为如何进一步调试问题,所以我在这里不知所措。任何人提供帮助?

感谢

回答

0

要回答我自己,我解决了这个问题由

plt.draw() 

后加入

plt.pause(0.01) 

这可能允许GUI来完成绘图,有的地方清空缓冲区(我的猜测)在新数据进来之前。

1

我不确定是否加plt.pause将完全解决您的问题。在应用程序崩溃之前可能需要更长的时间。您的应用程序使用的内存似乎随着时间的推移而不断增加(即使在添加plt.pause之后)。以下是两个建议,可以帮助您与您的当前问题:

  1. 而不是删除/与removeplot每次迭代重建线的艺术家,我会用同样的艺术家在整个动画,简单地更新其ydata

  2. 我会用明确的处理程序斧头和图形,并通过调用pyplotshow明确draw图上managercanvas,而不是与隐电话去,下面的post by tcaswell给出的建议。

按照上面的代码看起来是这样的:

import numpy as np 
import matplotlib.pyplot as plt 

fig, ax = plt.subplots() 
ax.axis([0, 100, 0, 1]) 

y = np.random.rand(100) 
lines = ax.plot(y) 

fig.canvas.manager.show() 

i=0 
while 1: 
    i=i+1 
    y = np.random.rand(100) 
    lines[0].set_ydata(y) 
    fig.canvas.draw() 
    fig.canvas.flush_events() 

我已经运行上面的代码有一个良好的10分钟,由应用程序所使用的内存保持稳定整个时间,而当前代码使用的内存(无plt.pause)在同一时期增加了大约30MiB。

0

我知道我很迟才回答这个问题,但对于您的问题,您可以查看“游戏杆”包。它基于line.set_data()和canvas.draw()方法,可选轴重新缩放,因此最有可能比删除一行和添加一行更快。它还允许交互式文本记录或图形绘制(除了图形绘制)。 没有必要在一个单独的线程中做自己的循环,软件包会照顾它,只是给你想要的更新频率。另外终​​端仍然可用于更多的监控命令,而实时绘图,这是不可能与“真正的”循环。 见http://www.github.com/ceyzeriat/joystick/https://pypi.python.org/pypi/joystick(PIP使用操纵杆安装安装)

尝试:

import joystick as jk 
import numpy as np 
import time 

class test(jk.Joystick): 
    # initialize the infinite loop decorator 
    _infinite_loop = jk.deco_infinite_loop() 

    def _init(self, *args, **kwargs): 
     """ 
     Function called at initialization, see the doc 
     """ 
     self._t0 = time.time() # initialize time 
     self.xdata = np.array([self._t0]) # time x-axis 
     self.ydata = np.array([0.0]) # fake data y-axis 
     # create a graph frame 
     self.mygraph = self.add_frame(jk.Graph(name="test", size=(500, 500), pos=(50, 50), fmt="go-", xnpts=100, xnptsmax=1000, xylim=(None, None, 0, 1))) 

    @_infinite_loop(wait_time=0.2) 
    def _generate_data(self): # function looped every 0.2 second to read or produce data 
     """ 
     Loop starting with the simulation start, getting data and 
    pushing it to the graph every 0.2 seconds 
     """ 
     # concatenate data on the time x-axis 
     self.xdata = jk.core.add_datapoint(self.xdata, time.time(), xnptsmax=self.mygraph.xnptsmax) 
     # concatenate data on the fake data y-axis 
     self.ydata = jk.core.add_datapoint(self.ydata, np.random.random(), xnptsmax=self.mygraph.xnptsmax) 
     self.mygraph.set_xydata(t, self.ydata) 

t = test() 
t.start() 
t.stop()