2013-01-21 11 views
0

wxPython中的圖形數據有問題 - 下面的代碼可行,但它不完全正確:現在我繪製的是隨機數,它是輸入框的倍數,每100ms完成一次。wxPython - 製圖數據

我的問題是,數字的整個歷史記錄顯示爲一個姿勢是一個(說)25個樣本的運行窗口。我最初嘗試在100個樣本的每個集合上重新繪製圖表,例如if(length(data)%100): drawGraph,但是這看起來不正確。

想法和建議歡迎。

我的代碼:

print("\n- Please Wait -- Importing Matplotlib and Related Modules...\n") 
import random 
import matplotlib 
import numpy 
import wx 
import u3 
import numpy as np 
matplotlib.use('WXAgg') 

from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas 
from matplotlib.backends.backend_wx import NavigationToolbar2Wx 
from matplotlib.figure import Figure 


class TemperaturePanel(wx.Panel) : 
    def __init__(self, parent, position) : 
     wx.Panel.__init__(self, parent, pos=position, size=(800,320)) 
     # initialize matplotlib 
     self.figure = matplotlib.figure.Figure(None, facecolor="white") 
     self.canvas = matplotlib.backends.backend_wxagg.FigureCanvasWxAgg(self, -1, self.figure) 
     self.axes = self.figure.add_subplot(111) 
     self.axes.grid(True, color="gray") 
     self.axes.set_xbound((0,5)) 
     self.axes.set_ybound((3,80)) 
     self.axes.set_xlabel("Minutes") 
     self.axes.set_ylabel("Temperature ($^\circ$C)") 
     self.axes = self.figure.add_subplot(111) 
     self.axes.grid(True, color="gray") 
     self._SetSize() 
     self.Bind(wx.EVT_SIZE, self._SetSize) 
     self.TemperatureData = [] 

    def updateTemperature(self, value): 
     self.TemperatureData.append(value) 
     length = len(self.TemperatureData) 
     x = np.arange(length) 
     y = np.array(self.TemperatureData) 

     yMin = round(min(y)) - 2 
     yMax = round(max(y)) + 2    
     self.axes.plot(x,y, "-k") 
     self.axes.set_ybound((yMin,yMax)) 
     self.canvas = FigureCanvas(self, -1, self.figure) 

    #----------------------------------------------------------------------------------- 
    def _SetSize(self, event=None): 
     pixels = self.GetSize() 
     self.SetSize(pixels) 
     self.canvas.SetSize(pixels) 

     dpi = self.figure.get_dpi() 
     self.figure.set_size_inches(float(pixels[0])/dpi,float(pixels[1])/dpi) 
    #------------------------------------------------------------------------------------ 




class MainWindow(wx.Frame): 
    def __init__(self, parent): 
     #wx.Frame.__init__(self, *args, **kwargs) 
     wx.Frame.__init__(self, parent, title="Graph Issue", size=(1000,600)) 
     self.panel = wx.Panel(self) 
     self.spin = wx.SpinCtrl(self.panel) 
     self.button = wx.Button(self.panel, label="Update") 
     self.stop = wx.Button(self.panel, label="Stop") 

     self.sizer = wx.BoxSizer() 
     self.sizer.Add(self.spin) 
     self.sizer.Add(self.button) 
     self.sizer.Add(self.stop) 

     self.TemperatureGraph = TemperaturePanel(self, position=(20, 50)) 
     self.panel.SetSizerAndFit(self.sizer) 
     self.Show() 

     # Use EVT_CHAR_HOOK on Frame insted of wx.EVT_KEY_UP on SpinCtrl 
     # to disable "on Enter go to next widget" functionality 
     self.Bind(wx.EVT_CHAR_HOOK, self.OnKey) 
     self.button.Bind(wx.EVT_BUTTON, self.OnUpdate) 
     self.stop.Bind(wx.EVT_BUTTON, self.OnStop) 

     self.timer = wx.Timer(self) 
     self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) 
     self.Bind(wx.EVT_TIMER, self.updateTemperature, self.timer) 
     self.timer.Start(100) 
     self.value = 0 

    def OnKey(self, e): 
     if e.GetKeyCode() == wx.WXK_RETURN: # Is the key ENTER? 
      self.value = self.spin.GetValue() # Read SpinCtrl and set internal value 
     else:         # Else let the event out of the handler 
      e.Skip() 

    def OnUpdate(self, e): 
     self.value = self.spin.GetValue() # Read SpinCtrl and set internal value 

    def OnTimer(self, e): 
     # Show internal value 
     print(self.value) 

    def updateTemperature(self, e): 
     Temperature  = self.value*random.uniform(-1,1)    # obtain currnt temperature 
     self.TemperatureGraph.updateTemperature(Temperature)    # add temperature to graph 

    def OnStop(self, e): 
     self.timer.Stop() 
     self.Destroy() 


app = wx.App(False) 
win = MainWindow(None) 
app.MainLoop() 
+0

我不明白你的問題。我建議您從「我的問題...」開始重寫或編輯您的段落。第一句對我來說沒有意義,對於下一句和最後一句,「看起來不正確」並不是很有意義。 – tom10

+0

感謝那個tom10 - 安德烈索博列夫明白了 –

回答

1

如果我理解正確的問題,你需要25個最後溫度值僅在你的圖表,而不是值的所有歷史記錄中顯示。如果這是你想要的東西,然後在updateTemperature子程序只有最後25個值應該畫在:

if length < 25: 
    x = np.arange(length) 
    y = np.array(self.TemperatureData) 
else: 
    x = np.arange(length-25, length) 
    y = np.array(self.TemperatureData)[-25:] 

爲了讓劇情更好看,X軸可以調整你帶Y軸做同樣的方式:

xMin = 0 if length < 25 else length-25 
xMax = 25 if length < 25 else length 
self.axes.set_xbound((xMin,xMax)) 

如果情節看起來沒給你,這個問題是關於引起〜200次迭代後的圖形凍結內存泄漏,這是由於在每一個溫度更新創造FigureCanvas。相反,你可以重新使用現有的FigureCanvas,改變updateTemperature最後一行

self.canvas.draw()