2016-02-25 159 views
1

首先,对不起,这lenghty文本matplotlib的性能问题。我是python和matplotlib的新手,请耐心等待。需要帮助解决在树莓派

作为后续此question我发现生成网格是使用的web2py上的覆盆子裨相当费时的方法。我有一个CSV文件与四围12K线看起来像这样:

1;1.0679759979248047;0.0;147.0;0.0;;{'FHR1': 'US', 'FHR2': 'INOP', 'MHR': 'INOP'};69;good;;;;1455891539.502167 

的事情是,读那些12K线与numpy.genfromtxt已经花费30秒的东西。然后填充图表(没有花哨格子)花费了30秒,只是使用该csv的第1,3和7列。但是在将解决方案时间增加到170秒后。所以现在我必须弄清楚如何将时间消耗减少到不到一分钟。

我首先想到的就是要消除CSV - 我是一个读取数据,无论如何,这样我就可以跳过由要么保持内存中的数据或只是写它变成剧情的时候了。这就是我所做的,在我看来,简单的测试布局和使用pdf后端。我选择每次将数据写入图表,并在传输完成后保存图表。我认为应该可以正常工作,但事实并非如此。我不断收到可笑的错误:

RuntimeError: RRuleLocator estimated to generate 9178327 ticks from 0001-01-01 15:20:31.883239+00:00 to 0001-04-17 20:52:39.779205+00:00: exceeds Locator.MAXTICKS * 2 (6000000)

相信我,我一直在提高这些maxticks每试运行到顶部错误消息说数。它的可笑,因为这消息是数据仅仅60秒,我想去的地方近24 小时数据。我要么RRuleLocator停止估计,要么只是闭嘴,等待数据结束。我真的不认为我可以将MCVE制作出来,但我可以挖掘出我最可能搞砸的细节。

首先,我得到了一些课程设置,所以没有全局。为了简化,我有一个通信类,它每隔一秒读取一次串口。这是运行良好,直到昨天写入任何进入串口到csv。现在我想知道在获取数据的同时是否可以填充图表,并在完成后保存它。因此,对于测试中,我已将此添加到我的.py

import matplotlib 
matplotlib.use('PDF') # I want a PDF in the end 
from matplotlib import dates 
import matplotlib.pyplot as plt 
import numpy as np 
from numpy import genfromtxt 

那么一些成员对通信类,即来自绘图部分,主要是上面提到的解决方案。我初始化它们中的类INIT

self.fig = None 
    self.ctg = None 
    self.toco = None 

然后我有这样的方法我打电话,以便图表可以用于填充数据来制备一次我觉得我接收数据是在正确的形式/状态

def prepchart(self): 
    # how often to show xticklabels and repeat yticklabels: 
    print('prepchart') 
    xtickinterval = 5 

    hfmt = dates.DateFormatter('%H:%M:%S') 
    self.fig = plt.figure() 

    self.ctg = self.fig.add_subplot(2, 1, 1) # two rows, one column, first plot 
    plt.ylim(50, 210) 

    self.toco = self.fig.add_subplot(2, 1, 2) 
    plt.ylim(0, 100) 
    # Set the minor ticks to every 30 seconds 
    minloc = dates.SecondLocator(bysecond=[0,30]) 
    minloc.MAXTICKS = 3000000 
    self.ctg.xaxis.set_minor_locator(minloc) 
    # self.ctg.xaxis.set_minor_locator(dates.MinuteLocator()) 
    self.ctg.xaxis.set_major_formatter(hfmt) 

    self.toco.xaxis.set_minor_locator(dates.MinuteLocator()) 
    self.toco.xaxis.set_major_formatter(hfmt) 

    # actg.xaxis.set_ticks(rotation=45) 
    plt.xticks(rotation=45) 

然后每隔一段时间一旦我有我的数据要绘制我将在我的数据处理方法做到这一点

self.ctg.plot_date(timevalue, heartrate, '-') 
self.toco.plot_date(timevalue, toco, '-') 

最后一次没有更多的数据被发送(这可能是一分钟或24小时后)我会打电话给

def handleCTG(self): 
     self.fig.savefig('/home/pi/test.pdf') 

结论:我是不是在这个完全错误的去或有只是一个错误在我的代码?这真的是减少生成图表的等待时间吗?

+0

我对这应该如何工作有一个想法,但如何做到这一点我不知道。这个想法是,考虑到这个事实,我想要一个固定尺寸的轴(1cm == 60s),只需渲染这些碎片并将它们按上述间隔一个接一个地粘合在一起就没有问题。从而扩大渲染时间。从串行端口读取程序时,大部分时间都在等待(至少85%的空闲时间),它可以利用这段时间来做其他事情。 – Sherlock70

回答

1

好了,所以这里的交易。很明显,web2py运行的是一艘相当紧凑的船。这意味着没有太多的线程在浮动,它肯定不会为我的小图创建启动一个新线程。我注意到了这一点,当时我遵循Raspis任务管理器的CPU使用率,只看到了25%左右的内容。现在树莓派有4个内核...去做数学。首先,我在Raspi上的web2py之外运行我的脚本,并且看到,包括csv-reading和图表渲染在内的整个事情只需要20s。从那里开始(灵感来自How to run a task outside web2py and retrieve the output)这是一块蛋糕:使用有据可查的子进程用这个脚本调用一个新的python并完成。非常感谢任何给予这个想法的人。