Вопрос

Я разрабатывал графический интерфейс для непрерывного чтения данных с последовательного порта.После считывания данных будут выполнены некоторые вычисления, и результаты будут выведены на график и обновлены (также известное как динамическое построение графика).Для этих целей я использую серверную часть wx, предоставленную в matplotlib.Чтобы сделать это, я в основном использую массив для хранения своих результатов, к которому я продолжаю добавлять его после каждого вычисления и пересчитываю весь график.Чтобы сделать его "динамичным", я просто устанавливаю нижний и верхний пределы оси x для каждой итерации.Что-то похожее найдено в:

http://eli.thegreenplace.net/2008/08/01/matplotlib-with-wxpython-guis/

Проблема, однако, заключается в том, что, поскольку данные являются непрерывными, и если я продолжу выводить их на график, в конечном итоге системная память закончится и система выйдет из строя.Есть ли какой-нибудь другой способ, которым я могу непрерывно отображать свой результат?

Это было полезно?

Решение

Для этого я в основном использую массив для хранения моих результатов, в котором я сохраняю добавляя его в

Попробуйте ограничить размер этого массива, либо удалив старые данные, либо удалив каждую n-ю запись (разрешение экрана в любом случае не позволит отображать все записи).Я предполагаю, что вы записываете все данные на диск, чтобы ничего не потерять.

Кроме того, проанализируйте свой код на предмет утечек памяти.Материал, который вы используете и который вам больше не нужен, но который не собирается как мусор, потому что у вас все еще есть ссылка на него.

Другие советы

Я создал такой компонент с помощью питонов Tkinter.Источник здесь.

По сути, вам нужно сохранить построенные данные. где-то.Вы не можете хранить бесконечное количество точек данных в памяти, поэтому вам придется либо сохранить их на диск, либо перезаписать старые точки данных.

Данные и представление данных — две разные вещи.Возможно, вы захотите сохранить свои данные на диске, если это важные данные для последующего анализа, но сохраняйте только фиксированный период времени или последние N точек для отображения.Вы даже можете позволить пользователю выбрать временной интервал для отображения.

Я действительно столкнулся с этой проблемой (на самом деле это скорее ментальный блок...).

Прежде всего, я скопировал код wx Plot из Демо-код wx.

Что я делаю, так это веду журнал значений в реальном времени и сравниваю их с двумя маркерами (минимальный и максимальный, показанные в виде красных и зеленых пунктирных линий) (но я сделаю эти два маркера необязательными - отсюда и необязательные параметры).

Чтобы реализовать живой журнал, я сначала хотел использовать класс deque, но, поскольку данные находятся в режиме кортежа (координаты x,y), я сдался и просто попытался переписать весь список параметров кортежей:см. _update_coordinates.

Он отлично работает для отслеживания последних 100-10 000 участков.Еще бы включил принтскрин, но я слишком нуб в stackoverflow, чтобы это можно было разрешить :))

Мой живой параметр обновляется каждые 0,25 секунды по UART со скоростью 115 кбит/с.

Хитрость в конце, в пользовательском методе обновления!

Вот большая часть кода:

class DefaultPlotFrame(wx.Frame):
    def __init__(self, ymin=0, ymax=MAXIMUM_PLOTS, minThreshold=None, 
             maxThreshold=None, plotColour='blue',
             title="Default Plot Frame", 
             position=(10,10),
             backgroundColour="yellow", frameSize=(400,300)):

        self.minThreshold = minThreshold
        self.maxThreshold = maxThreshold
        self.frame1 = wx.Frame(None, title="wx.lib.plot", id=-1, size=(410, 340), pos=position)
        self.panel1 = wx.Panel(self.frame1)
        self.panel1.SetBackgroundColour(backgroundColour)
        self.ymin = ymin
        self.ymax = ymax
        self.title = title
        self.plotColour = plotColour

        self.lines = [None, None, None]                

       # mild difference between wxPython26 and wxPython28        
       if wx.VERSION[1] < 7:
           self.plotter = plot.PlotCanvas(self.panel1, size=frameSize)
       else:
           self.plotter = plot.PlotCanvas(self.panel1)
       self.plotter.SetInitialSize(size=frameSize)
       # enable the zoom feature (drag a box around area of interest)
       self.plotter.SetEnableZoom(False)

       # list of (x,y) data point tuples        
       self.coordinates = []   
       for x_item in range(MAXIMUM_PLOTS):
           self.coordinates.append((x_item, (ymin+ymax)/2))

       self.queue = deque(self.coordinates)            

       if self.maxThreshold!=None:            
           self._update_max_threshold()             
       #endif           

       if self.lockThreshold!=None:            
           self._update_min_threshold()            
       #endif

       self.line = plot.PolyLine(self.coordinates, colour=plotColour, width=1)                
       self.lines[0] = (self.line)                                                     

       self.gc = plot.PlotGraphics(self.lines, title, 'Time', 'Value')
       self.plotter.Draw(self.gc, xAxis=(0, MAXIMUM_PLOTS), yAxis=(ymin, ymax))            

       self.frame1.Show(True)

    def _update_max_threshold(self):
        if self.maxThreshold!=None:
           self.maxCoordinates = []
           for x_item in range(MAXIMUM_PLOTS):
               self.maxCoordinates.append((x_item, self.maxThreshold))
           #endfor
           self.maxLine = plot.PolyLine(self.maxCoordinates, colour="green", width=1)
           self.maxMarker = plot.PolyMarker(self.maxCoordinates, colour="green", marker='dot')
           self.lines[1] = self.maxMarker 
        #endif  

   def _update_live_param(self, liveParam, minParam, maxParam):
        if minParam!=None:
            self.minThreshold = int(minParam)
            self._update_min_threshold()
        #endif

        if maxParam!=None:
            self.maxThreshold = int(maxParam)
            self._update_max_threshold() 
        #endif

        if liveParam!=None:            
            self._update_coordinates(int(liveParam))
        #endif

    def _update_coordinates(self, newValue):
        newList = []         
        for x,y in self.coordinates[1:]:            
            newList.append((x-1, y))
        #endfor
        newList.append((x, newValue))
        print "New list", newList

        self.line = (plot.PolyLine(newList, colour=self.plotColour, width=1))
        self.lines[0] = self.line
        self.coordinates = newList

    def _MyLIVE_MAGIC_refresh__(self, liveParam=None, minParam=None, maxParam=None):   
        self._update_live_param(liveParam, minParam, maxParam)
        self.gc = plot.PlotGraphics(self.lines, self.title, 'Time', 'Value')
        self.plotter.Draw(self.gc, xAxis=(0, MAXIMUM_PLOTS), yAxis=(self.ymin, self.ymax))            
        self.plotter.Refresh()            
        self.frame1.Refresh()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top