2017-04-21 209 views
0

我正在试图在wx.Panel中为活动图形制作动画。我想要x轴更新像this example。我看到的很多例子都是基本的,并没有考虑到班级中的其他控制和功能。其他人有很多额外的东西,我迷失在杂草丛中。我无法在正确的位置获得动画命令或更新x轴。这里是代码:更新wxPython面板中的matplotlib动态图表,滚动x轴

import wx 
import logging 
import numpy as np 
import matplotlib 
import time 
import matplotlib.animation as animation 

matplotlib.use('WXAgg') 

import matplotlib.pyplot as plt 

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

fTemp = "" 
x = 0 

class TempClass(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, -1, title="", size=(600,500)) 
     panel = wx.Panel(self) 

     self.fig = Figure(figsize=(6,4), dpi=75, facecolor='lightskyblue', edgecolor='r') 
     self.canvas = FigureCanvas(self, -1, self.fig) 
     self.ax = self.fig.add_subplot(111) 

     self.ax2 = self.ax.twinx() 
     self.ax.set_ylim(60,90) 
     self.ax.set_xlim(0,24) 
     self.ax2.set_ylim(0,100) 

     # major ticks every 5, minor ticks every 1          
     xmajor_ticks = np.arange(0, 24, 5)            
     xminor_ticks = np.arange(0, 24, 1)            

     self.ax.set_xticks(xmajor_ticks)              
     self.ax.set_xticks(xminor_ticks, minor=True)           
     self.ax.grid() 

     self.ax.set_xlabel('Hour') 
     self.ax.set_ylabel('Temp') 
     self.ax2.set_ylabel('Humidity') 
     self.ax.set_title('Temperature') 

     # The graph does not show in the panel when this in uncommented 
     #self.ani = animation.FuncAnimation(self.fig, self.onPlotTemp, interval=1000) 

     self.fanSensorTimer = wx.Timer(self) 
     self.Bind(wx.EVT_TIMER, self.onPlotTemp, self.fanSensorTimer) 

     self.fanSensorBtn = wx.Button(self, -1, "Start Sensor") 
     self.Bind(wx.EVT_BUTTON, self.onStartTempPlot, self.fanSensorBtn) 

     font1 = wx.Font(18, wx.DEFAULT,wx.NORMAL,wx.BOLD) 
     self.displayTemp = wx.StaticText(self, -1, "Current Tempurature") 
     self.curTempTxt = wx.TextCtrl(self, -1, "0",size=(100,40), style=wx.TE_READONLY|wx.TE_CENTRE|wx.BORDER_NONE) 
     self.curTempTxt.SetFont(font1) 
     self.displayHum = wx.StaticText(self, -1, "Current Humidity") 
     self.curHumTxt = wx.TextCtrl(self, -1,"0", size=(100,40), style=wx.TE_READONLY|wx.TE_CENTRE|wx.BORDER_NONE) 
     self.curHumTxt.SetFont(font1) 

     self.displayBox = wx.GridBagSizer(hgap=5,vgap=5) 
     self.displayBox.Add(self.displayTemp, pos=(0,0), flag=wx.TOP|wx.LEFT, border=5) 
     self.displayBox.Add(self.displayHum, pos=(0,1), flag=wx.TOP, border=5) 
     self.displayBox.Add(self.curTempTxt, pos=(1,0), flag=wx.ALL, border=5) 
     self.displayBox.Add(self.curHumTxt, pos=(1,1), flag=wx.ALL, border=5) 

#--------- 
     self.vbox = wx.BoxSizer(wx.VERTICAL) 
     self.vbox.Add(self.canvas, wx.ALIGN_CENTER|wx.ALL, 1) 
     self.vbox.Add(self.fanSensorBtn) 
     self.vbox.Add(self.displayBox, wx.ALIGN_CENTER|wx.ALL, 1) 
     self.SetSizer(self.vbox) 
     self.vbox.Fit(self) 

    def start(self): 
     # get temp/humidity reading from node 
     pass 


    def readTemp(self, data1, data2): 
     "Populates Current Temp" 
     global fTemp 
     self.curTempTxt.Clear() 
     a = format(data1, '08b') 
     b = format(data2, '08b') 
     x = a+b 
     y = int(x, base=2) 
     cTemp = ((175.72 * y)/65536)-46.85 
     fTemp = cTemp *1.8+32 
     cel = format(cTemp,'.1f') 
     far = format(fTemp,'.1f') 
     self.curTempTxt.WriteText(far + (u'\u00b0')+"F") 

    def rh1(self, data1, data2): 
     "Populates Current RH" 
     global relhum 
     self.curHumTxt.Clear() 
     a = format(data1, '08b') 
     b = format(data2, '08b') 
     x = a+b 
     y = int(x, base=2) 
     rh = ((125 * y)/65536)-6 
     relhum = format(rh,'.1f') 
     self.curHumTxt.WriteText(relhum + " %") 


    def onStartTempPlot(self,event): 
     #set for a short time period for testing purposes 
     self.fanSensorTimer.Start(5000) 
     print "Timer Started" 

    def onPlotTemp(self,event): 
     global fTemp, x, relhum 
     x +=1 
     y = int(fTemp) 
     y2 = float(relhum) 

     self.ax.plot(x,y,'r.') 
     self.ax2.plot(x,y2,'k.') 

     self.fig.canvas.draw() 

     # send message to node for another reading of temp/humidity 


if __name__ == "__main__": 
    app = wx.App(False) 
    frame = TempClass() 
    frame.Show() 
    frame.start() 
    logging.basicConfig(level=logging.DEBUG) 
    app.MainLoop() 

我希望看到X轴增量作为数据被绘制超出图上的24小时点;当点25的数据出现时,第一个点被丢弃,x轴显示'25'。动画被注释掉,因为它会导致图形消失,直到绘制一个点。

这里是我试图实现与x轴的可运行的例子:

import numpy 
    from matplotlib.pylab import * 
    from mpl_toolkits.axes_grid1 import host_subplot 
    import matplotlib.animation as animation 


    # Sent for figure 
    font = {'size' : 9} 
    matplotlib.rc('font', **font) 

    # Setup figure and subplots 
    f0 = figure(num = 0, figsize = (6, 4))#, dpi = 100) 
    f0.suptitle("Oscillation decay", fontsize=12) 
    ax01 = subplot2grid((2, 2), (0, 0)) 

    # Set titles of subplots 
    ax01.set_title('Position vs Time') 

    # set y-limits 
    ax01.set_ylim(0,2) 

    # sex x-limits 
    ax01.set_xlim(0,1) 

    # Turn on grids 
    ax01.grid(True) 

    # set label names 
    ax01.set_xlabel("x") 
    ax01.set_ylabel("py") 

    # Data Placeholders 
    yp1=zeros(0) 
    yv1=zeros(0) 
    yp2=zeros(0) 
    yv2=zeros(0) 
    t=zeros(0) 

    # set plots 
    p011, = ax01.plot(t,yp1,'b-', label="yp1") 
    p012, = ax01.plot(t,yp2,'g-', label="yp2") 

    # set lagends 
    ax01.legend([p011,p012], [p011.get_label(),p012.get_label()]) 


    # Data Update 
    xmin = 0 
    xmax = 24 
    x = 0 

    def updateData(self): 
      global x 
      global yp1 
      global yv1 
      global yp2 
      global yv2 
      global t 

      tmpp1 = 1 + exp(-x) *sin(2 * pi * x) 
      tmpv1 = - exp(-x) * sin(2 * pi * x) + exp(-x) * cos(2 * pi * x) * 2 * pi 
      yp1=append(yp1,tmpp1) 
      yv1=append(yv1,tmpv1) 
      yp2=append(yp2,0.5*tmpp1) 
      yv2=append(yv2,0.5*tmpv1) 
      t=append(t,x) 

      x += 1 

      p011.set_data(t,yp1) 
      p012.set_data(t,yp2) 

      if x >= xmax-1: 
        p011.axes.set_xlim(x-xmax+1,x+1) 

      return p011 

    # interval: draw new frame every 'interval' ms 
    # frames: number of frames to draw 
    simulation = animation.FuncAnimation(f0, updateData, blit=False, frames=200, interval=20, repeat=False) 


    plt.show() 
+0

尝试从tempPlot函数中删除行'self.ax = self.figure.add_subplot(111)',否则在动画的每次迭代中重新创建self.ax。 – ImportanceOfBeingErnest

+0

我试过了,我无法让你的建议工作。我重新编写了一些代码并编辑了我的问题。希望新代码能够显示我遇到的问题。谢谢@ImportanceOfBeingErnest –

+0

现在我正在“迷失在杂草丛中”。这是重现问题所需的[mcve]吗?您也没有明确的问题描述。你遇到的问题究竟是什么? FuncAnimation在哪里去了? – ImportanceOfBeingErnest

回答

1

你是不是增加了X轴限制或蜱。

def onPlotTemp(self,event): 
    global fTemp, x, relhum 
    x +=1 
    y = int(fTemp) 
    y2 = float(relhum) 
    if x >= 24-1: 
      self.ax.set_xlim(x-24+1,x+1) 
      xmajor_ticks = np.arange(x-24+1,x+5, 5) 
      xminor_ticks = np.arange(x-24+1, x+1,1) 
      self.ax.set_xticks(xmajor_ticks) 
      self.ax.set_xticks(xminor_ticks, minor=True) 

    self.ax.plot(x,y,'r.') 
    self.ax2.plot(x,y2,'k.') 

    self.fig.canvas.draw() 

我不确定上述是否按照您希望的方式重置剔号,但您明白了。很显然,我已经将24作为限制进行了硬编码,您可能需要创建一个变量来对其进行排序。

+0

这样做!谢谢。 –