Пример #1
0
 def OnLeftMouseDblClick(self, event):
     if not self.active:
         return False
     if self.gpx != None:
         l = ''
         for name in self.gpx.get_header_names() + ['use custom color']:
             l += '|' + name
         (dummy,self.trackcolorkey, self.linewidth,self.trackcolordefault,\
         dummy,self.currentindic,self.currentcolor,self.currentthetakey,\
         self.currentmagkey,self.currentzoom)=WxQuery("color table to use",
                                         [('wxnotebook','Track',None,None,None),\
                                          ('wxcombo','Key for color code',l[1:],self.trackcolorkey,'str'),\
                                          ('wxspin','Line width','1|10|1',self.linewidth,'float'),\
                                          ('wxcolor','Custom color',None,self.trackcolordefault,'float'),\
                                          ('wxnotebook','Indicator',None,None,None),\
                                          ('wxcombo','Style','Dot|Arrowhead|Vector from|Vector to',self.currentindic,'str'),\
                                          ('wxcolor','Custom color',None,self.currentcolor,'float'),\
                                          ('wxcombo','Key for angle',l[1:],self.currentthetakey,'str'),\
                                          ('wxcombo','Key for magnitude',l[1:],self.currentmagkey,'str'),
                                          ('wxspin','Zoom factor','0|150|1',str(self.currentzoom),'float')])
         self.trackcolordefault += (1.0, )
         self.currentcolor += (1.0, )
         self.BuildColorTable(self.trackcolorkey)
         self.parent.Draw()
         return True
Пример #2
0
 def OnAnalyseButton(self, event):
     doorliststr = ','.join(
         str(e) for e in range(0, len(self.waypointslayer.doors)))
     (waypointsstr,disableoutside)=WxQuery('Comma separated list of doors',\
                 [('wxentry','WayPoints',None,doorliststr,'str'),\
                  ('wxcheck','Disable invalid points',None,self.disableoutside,'bool')])
     self.waypoints = map(int, waypointsstr.split(','))
     self.disableoutside = disableoutside
     self.Analyse()
Пример #3
0
def test_wxquery():
    entries = [
        ('wxnotebook', 'Entry', None, None, None),  #0
        ('wxentry', 'Textual entry', None, 'default_value', 'str',
         'this is an optionnal tooltip'),
        ('wxentry', 'Integer entry', None, 127, 'int'),
        ('wxentry', 'Floating point value entry', None, 127.30, 'float'),
        ('wxnotebook', 'Combo/list', None, None, None),
        ('wxcombo', 'Textual Combo', 'choice1|choice2|choice3', 'choice2',
         'str'),  #5
        ('wxcombo', 'Integer Combo', '125|2|1538', 2, 'int'),
        ('wxcombo', 'Float Combo', '12.5|2.0|1.538', 2, 'float'),
        ('wxlist', 'List', 'January|February|March|April|May|June', 'April',
         'str'),
        ('wxnotebook', 'Spin/Range', None, None, None),
        ('wxspin', 'Integer spin', '1|13|2', 6, 'int'),  #10
        ('wxspin', 'Float spin', '0.321|10.321|0.100', 3.701234567, 'float'),
        ('wxhscale', 'Integer range', '0|12|1|0', 6, 'int'),
        ('wxhscale', 'Float range', '0|12|1|0', 6, 'float'),
        ('wxnotebook', 'CheckBox and radio', None, None, None),
        ('wxcheck', 'CheckBox', None, False, 'bool'),  #15
        ('wxradio', 'Radio', 'One|Two|Three|Four|Five', 'Three', 'str'),
        ('wxnotebook', 'Date/Time', None, None, None),
        ('wxdate', 'Date', '2014-01-10|2015-05-10', '2015-03-10', 'str'),
        ('wxtime', 'Time', '00:00:00|23:59:59', '12:30:17', 'str'),
        ('wxcalendar', 'Calendar', '2014-05-10|2015-05-10', '2015-05-10',
         'str'),  #20
        ('wxnotebook', 'Static', None, None, None),
        ('wxlabel', 'A label', None, 'Second part of label', 'str',
         'tooooltiiip'),
        ('wximage', 'An Image', '32|32', thispath() + "/images/map.png",
         'str'),
        ('wxnotebook', 'Picker', None, None, None),
        ('wxcolor', 'Color Picker', None, '#AA0055', 'str'),  #25
        ('wxcolor', 'Color Picker (int)', None, (255, 0, 0), 'int'),
        ('wxcolor', 'Color Picker (float)', None, (1.0, 0.0, 0.0), 'float'),
        ('wxfile', 'File picker', 'Acrobat files (*.pdf)|*.pdf', "C:\\", 'str',
         'extra1', 23.154),
        #('wxfile','File picker','',"C:\\",'str','extra1',23.154),
        ('wxdir', 'Dir picker', None, "C:\\", 'str'),
        ('wxnotebook', 'Checkbox', None, None, None),  #30
        ('wxcheck', 'CheckBox', '32|-33|34|-35', True, 'bool'
         ),  # special syntax list of controls to enable disable with checkbox
        ('wxentry', 'enabled with check', None, 'default_value', 'str'),
        ('wxentry', 'disabled with check', None, 'default_value', 'str'),
        ('wxentry', 'enabled with check', None, 'default_value', 'str'),
        ('wxentry', 'disabled with check', None, 'default_value', 'str'),  #35
        ('wxentry', 'not affected', None, 'default_value', 'str'),
        ('wxnotebook', 'Checklist', None, None, None),
        ('wxchecklist', 'CheckList',
         'apple|orange|banana|pears|stawberry|pinapple|cherry|apple|orange|banana|pears|stawberry|pinapple|cherry',
         'apple|banana|pears', 'str')
    ]
    app = wx.App(False)
    print(WxQuery("A sample dialog", entries))
    app.MainLoop()
Пример #4
0
 def OnReplayMenu(self,event):
     if self.replaytimer==None:
         (speed,)=WxQuery("Replay speed: x",[("wxentry","Replay speed",None,"100",'int')])
         self.replaytimer=wx.Timer(self)
         self.Bind(wx.EVT_TIMER,self.OnReplayTimer,self.replaytimer)
         self.replaytimer.Start(speed)
         self.idx=self.selstart
         wx.GetApp().blockmousemotion=True
     else:
         self.replaytimer.Stop()
         self.replaytimer=None
         wx.GetApp().blockmousemotion=False
     pass
Пример #5
0
 def OnUnitsMenu(self,event):
     li=[]
     un='|'.join(gpxobj.units.keys())
     # as _x, _y, _r, _g, _b and _d are no more in gpx file, we could avoid checking first character...
     for head in self.gpx.get_header_names():
         if not head.startswith('_'):
             li.append(("wxcombo",str(head),un,self.gpx.get_unit(head)[0],'str'))
     res=WxQuery("Adjust units",li)
     i=0
     for head in self.gpx.get_header_names():
         if not head.startswith('_'):
             self.gpx.set_unit(head,res[i])
             i+=1
     msgwrap.message("ValChanged",arg1=self.id)
     self.Refresh()
Пример #6
0
 def SaveFile(self,filename):
     if 'wxShell' in self.plugins:
         self.plugins["wxShell"].run(thispath()+os.sep+"scripts"+os.sep+"onSaveFile.py")
     if filename[-4:]=='.npz' or filename[-4:]=='.NPZ':
         self.gpx.save_npz(filename)
     elif filename[-4:]=='.gpx' or filename[-4:]=='.GPX':
         allowedfields=self.gpx.get_header_names()
         allowedfields.remove('ok')
         allowedfields.remove('idx')
         allowedfields.remove('lat')
         allowedfields.remove('lon')
         (fields,save_enabled)=WxQuery("GPX export dialog",\
                                 [('wxchecklist','Choose fields to export','|'.join(allowedfields),'time|speed','str'), \
                                  ('wxcheck','Exported only enabled points',None,False,'bool')])
         if save_enabled:
             # np.where returns a tupple of numpy.ndarray where we need a list
             self.gpx.save_xml(filename,fields.split('|'),np.where(self.gpx['ok']==True)[0].tolist())
         else:
             self.gpx.save_xml(filename,fields.split('|'),None)
Пример #7
0
 def OnLeftMouseDblClick(self, event):
     if self.gpx != None:
         values = [x for x in self.gpx.get_header_names() if x != 'time']
         (self.key,self.size)=WxQuery("Value to monitor",\
             [
              ('wxcombo','Choose','|'.join(values),self.key,'str'),
              ('wxspin','Size','150|300|10',self.size,'int')
             ])
         self.speedmeter.SetMinSize(wx.Size(self.size, self.size))
         self.Layout()
         step = int(math.ceil(self.gpx[(self.key, 1, 1)].max() / 10))
         self.speedmeter.SetIntervals(range(0, step * 10 + 1, step))
         self.speedmeter.SetTicks(
             [str(interval) for interval in range(0, step * 10 + 1, step)])
         self.speedmeter.SetSpeedValue(self.gpx[(self.key, 1,
                                                 0)][self.current])
         self.speedmeter.SetMiddleText(self.gpx.get_unit(self.key)[0])
         self.l1.SetLabel("{:.2f} {}".format(
             self.gpx[(self.key, 1, 0)][self.current],
             self.gpx.get_unit(self.key)[0]))
Пример #8
0
 def OnLeftMouseDblClick(self, event):
     if self.gpx != None:
         values = [x for x in self.gpx.get_header_names() if x != 'time']
         (self.key,)=WxQuery("Value to monitor",\
             [
              ('wxcombo','Choose','|'.join(values),self.key,'str'),
             ])
         high = math.ceil(np.percentile(self.gpx[(self.key, 1, 1)], 90))
         low = math.ceil(np.percentile(self.gpx[(self.key, 1, 1)], 25))
         self.peakmeter.SetRangeValue(
             low, high, math.ceil(self.gpx[(self.key, 1, 1)].max()))
         self.peakmeter.SetData([self.gpx[(self.key, 1, 0)][self.current]],
                                0, 1)
         self.l1.SetLabel("{:.2f} {}".format(
             self.gpx[(self.key, 1, 0)][self.current],
             self.gpx.get_unit(self.key)[0]))
     else:
         print(os.path.dirname(os.path.abspath(__file__)))
         self.Screenshot(
             os.path.dirname(os.path.abspath(__file__)) + os.sep +
             'test.jpg')
Пример #9
0
 def OnLeftMouseDblClick(self, event):
     (dummy,xlo,xhi,ylo,yhi,self.autoscale,self.grid,\
     dummy,self.thetasrc,self.radiussrc,extra)=\
         WxQuery("Graph Settings",\
             [('wxnotebook','Axes',None,None,None),
              ('wxentry','Theta Low',None,self.ax.get_xlim()[0],'float'),
              ('wxentry','Theta High',None,self.ax.get_xlim()[1],'float'),
              ('wxentry','Radius Low',None,self.ax.get_ylim()[0],'float'),
              ('wxentry','Radius High',None,self.ax.get_ylim()[1],'float'),
              ('wxcheck','Autoscale',None,self.autoscale,'bool'),
              ('wxcheck','Show Grid',None,self.grid,'bool'),
              ('wxnotebook','Polar plot',None,None,None),
              ('wxcombo','Theta',self.XAxisAllowed(),self.thetasrc,'str'),
              ('wxcombo','Radius',self.XAxisAllowed(),self.radiussrc,'str'),
              ('wxentry','Extra arguments',None,{},'str')
             ])
     self.kwargs.update(ast.literal_eval(extra))
     if self.autoscale:
         self.Plot()
     else:
         self.Plot((xlo, xhi), (ylo, yhi))
Пример #10
0
 def OnLeftMouseDblClick(self, event):
     (dummy,xlo,xhi,ylo,yhi,self.autoscale,self.grid,\
     dummy,self.xsrc,self.ysrc,self.kwargs['marker'],self.kwargs['color'],extra)=\
         WxQuery("Graph Settings",\
             [('wxnotebook','Axes',None,None,None),
              ('wxentry','X Low',None,self.ax.get_xlim()[0],'float'),
              ('wxentry','X High',None,self.ax.get_xlim()[1],'float'),
              ('wxentry','Y Low',None,self.ax.get_ylim()[0],'float'),
              ('wxentry','Y High',None,self.ax.get_ylim()[1],'float'),
              ('wxcheck','Autoscale',None,self.autoscale,'bool'),
              ('wxcheck','Show Grid',None,self.grid,'bool'),
              ('wxnotebook','Scatter plot',None,None,None),
              ('wxcombo','X axis',self.XAxisAllowed(),self.xsrc,'str'),
              ('wxcombo','Y axis',self.XAxisAllowed(),self.ysrc,'str'),
              ('wxcombo','Symbol','.|o|+|x|^|4|s|*|D',self.kwargs['marker'],'str'),
              ('wxcolor','Color',None,self.kwargs['color'],'str'),
              ('wxentry','Extra arguments',None,"{}",'str')
             ])
     self.kwargs.update(ast.literal_eval(extra))
     if self.autoscale:
         self.Plot()
     else:
         self.Plot((xlo, xhi), (ylo, yhi))
Пример #11
0
 def OnColPopup(self, event):
     item = self.col_menu.FindItemById(event.GetId())
     text = item.GetText()
     key=self.gpxtable.gpx.get_header_names()[self.GetSelectedCols()[0]]
     if text=="Delete column":
         dlg = wx.MessageDialog(None, "Destroy col \" %s \"" % key,"Confirm",wx.OK|wx.CANCEL|wx.ICON_WARNING)
         if dlg.ShowModal()==wx.ID_OK:
             self.gpxtable.gpx.drop_column(key)
             tmpgpx=self.gpxtable.gpx
             self.DetachGpx()
             self.AttachGpx(tmpgpx)
         dlg.Destroy()
     elif text=="Append column":
         (name,)=WxQuery("New column",[("wxentry","Column name",None,"buffer",'str')])
         self.gpxtable.gpx.append_column(name,'float')
         tmpgpx=self.gpxtable.gpx
         self.DetachGpx()
         self.AttachGpx(tmpgpx)
     elif text=="Sort ascending":
         self.gpxtable.gpx.sort_asc(key)
     elif text=="Sort descending":
         self.gpxtable.gpx.sort_desc(key)
     self.ForceRefresh()
Пример #12
0
 def OnLeftMouseDblClick(self,event):
     (dummy,xlo,xhi,ylo,yhi,self.autoscale,self.grid,\
     dummy,self.barsrc,self.lo,self.hi,self.barbins,self.kwargs['color'],extra)=\
         WxQuery("Graph Settings",\
             [('wxnotebook','Axes',None,None,None),
              ('wxentry','X Low',None,self.ax.get_xlim()[0],'float'),
              ('wxentry','X High',None,self.ax.get_xlim()[1],'float'),
              ('wxentry','Y Low',None,self.ax.get_ylim()[0],'float'),
              ('wxentry','Y High',None,self.ax.get_ylim()[1],'float'),
              ('wxcheck','Autoscale',None,self.autoscale,'bool'),
              ('wxcheck','Show Grid',None,self.grid,'bool'),
              ('wxnotebook','Histogram',None,None,None),
              ('wxcombo','Category',self.XAxisAllowed(),self.barsrc,'str'),
              ('wxcombo','Start',str(self.lo)+'|'+str(min(self.gpx[(self.barsrc,1,1)])),str(self.lo),'float'),
              ('wxcombo','End',str(self.hi)+'|'+str(max(self.gpx[(self.barsrc,1,1)])),str(self.hi),'float'),
              ('wxspin','Number of bars','10|100|1',self.barbins,'int'),
              ('wxcolor','Color',None,self.kwargs['color'],'str'),
              ('wxentry','Extra arguments',None,{},'str')
             ])
     self.kwargs.update(ast.literal_eval(extra))
     if self.autoscale:
         self.Plot(self.lo,self.hi,self.barbins)
     else:
         self.Plot(self.lo,self.hi,self.barbins,(xlo,xhi),(ylo,yhi))
Пример #13
0
        def OpenFile(self,filename):
            #todo
            if not filename[-4:]in['.fit','.FIT','.npz','.NPZ','.gpx','.GPX','.xml','.XML']:
                return
            if self.gpx!=None:
                self.mapwidget.DetachGpx()
                self.timewidget.DetachGpx()
                for k in self.plugins:
                    self.plugins[k].DetachGpx()
                del self.gpx
            c=0
            progressdlg = wx.ProgressDialog("Loading", "Loading file", 17,style=wx.PD_SMOOTH|wx.PD_CAN_ABORT|wx.PD_AUTO_HIDE)
            self.gpx=gpxobj.GpxObj()                            ;c+=1;progressdlg.Update(c)
            if filename[-4:]=='.fit' or filename[-4:]=='.FIT':
                self.gpx.open_fit(filename)
            elif filename[-4:]=='.npz' or filename[-4:]=='.NPZ':
                self.gpx.open_npz(filename)
            else:
                self.gpx.open_gpx(filename)                     ;c+=1;progressdlg.Update(c,"Parsing file")
            #   self.gpx.parse_trkpts()                         ;c+=1;progressdlg.Update(c) # now included in open_gpx
            ## we calculate a few standard indicators:
            # deltat    time between two adjacent points. some GPS do not log at equally spaced times
            # deltaxy   horizontal distance between two ajacent points.
            # distance  cumulative distance calculated from haversine formula   (m)
            # duration  cumulative duration calculated from time tag            (s)
            # course   course calculated from haversine formula               (degrees)
            # speed     instantaneous speed calculated from haversine formula. only if no doppler speed is found
            # acc       instantaneous acceleration                              calculated drom speed column
            # slope     only if an elevation 'ele' tag is found                 instantaneous slope!!not reliable
            if not self.gpx.has_field('time'):
                # rare case, but time tag is not mandatory in gpx description
                dlg = wx.MessageBox('Your gpx file does not seem to include time values. Do you want to generate time series?','Generate fake times?', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION )
                if dlg == wx.YES:
                    deltat=WxQuery("Enter time gap between GPS points",[("wxentry","Time gap in seconds",None,"1.0",'float')])[0]
                    self.gpx.append_column('time','str')
                    base=datetime.datetime.today()
                    self.gpx['time']=[(base+datetime.timedelta(0,sec*deltat)).strftime("%Y-%m-%dT%H:%M:%SZ") for sec in range(0, self.gpx.get_row_count())]
            #some fields such as 'speed' or 'distance' may be directly imported from gpx/fit/tcx file
            if not self.gpx.has_field('deltat'):
                self.gpx.append_column('deltat','float')                ;c+=1;progressdlg.Update(c,"Computing Time deltas")
                self.gpx['deltat']=self.gpx.duration()                  ;c+=1;progressdlg.Update(c)
            if not self.gpx.has_field('deltaxy'):
                self.gpx.append_column('deltaxy','float')               ;c+=1;progressdlg.Update(c,"Computing Location deltas")
                self.gpx['deltaxy']=self.gpx.hv_distance()              ;c+=1;progressdlg.Update(c)
            if not self.gpx.has_field('distance'):
                self.gpx.append_column('distance','float')              ;c+=1;progressdlg.Update(c,"Computing distances")
                self.gpx['distance']=np.cumsum(self.gpx['deltaxy'])     ;c+=1;progressdlg.Update(c)
            if not self.gpx.has_field('duration'):
                self.gpx.append_column('duration','float')              ;c+=1;progressdlg.Update(c,"Computing durations")
                self.gpx['duration']=np.cumsum(self.gpx['deltat'])      ;c+=1;progressdlg.Update(c)
            if not self.gpx.has_field('course'):
                self.gpx.append_column('course','float')                ;c+=1;progressdlg.Update(c,"Computing course")
                self.gpx['course']=self.gpx.hv_course()                 ;c+=1;progressdlg.Update(c)
            if not self.gpx.has_field('speed'):
                self.gpx.append_column('speed','float')                 ;c+=1;progressdlg.Update(c,"Computing speed")
                self.gpx['speed']=self.gpx.hv_speed(True)               ;c+=1;progressdlg.Update(c)
            if not self.gpx.has_field('slope'):
                self.gpx.append_column('slope','float')                 ;c+=1;progressdlg.Update(c,"Computing slope")
                self.gpx['slope']=self.gpx.hv_slope(200,True)           ;c+=1;progressdlg.Update(c)
            progressdlg.Close()
            progressdlg.Destroy()
            self.gpx.set_unit('deltaxy','m')
            self.gpx.set_unit('deltat','s')
            # todo: check that the units are known
            self.gpx.set_unit('speed',self.config.get("units","default_speed_unit"))
            self.gpx.set_unit('distance',self.config.get("units","default_distance_unit"))
            self.gpx.set_unit('duration',self.config.get("units","default_time_unit"))
            #self.gpx.set_unit('speed','km/h')
            #self.gpx.set_unit('distance','m')
            #self.gpx.set_unit('duration','s')
            self.timewidget.AttachGpx(self.gpx)
            self.mapwidget.AttachGpx(self.gpx)
            self.gpxmenu.Enable(self.gpxmenu.FindItem("Units"),True)
            self.gpxmenu.Enable(self.gpxmenu.FindItem("Replay"),True)
            for k in self.plugins:
                self.plugins[k].AttachGpx(self.gpx)
            # new
            if 'wxShell' in self.plugins:
                self.plugins["wxShell"].run(thispath()+os.sep+"scripts"+os.sep+"onOpenFile.py")

            self.SetTitle(filename)
            self.__resize()
Пример #14
0
    def OnLeftMouseDblClick(self, event):
        #dble click. Let's get prepared
        xlo = self.num_to_x(self.ax1.get_xlim()[0], False)
        xhi = self.num_to_x(self.ax1.get_xlim()[1], False)
        y1lo = self.ax1.get_ylim()[0]
        y1hi = self.ax1.get_ylim()[1]
        y2lo = self.ax2.get_ylim()[0]
        y2hi = self.ax2.get_ylim()[1]
        y3lo = self.ax3.get_ylim()[0]
        y3hi = self.ax3.get_ylim()[1]

        (dummy,xaxis,xlo,xhi,self.cursorcolor,self.cursorwidth,
        dummy,self.plot1,y1lo,y1hi,self.autoy1,self.smooth1,
        self.lineprops1['color'],self.lineprops1['linewidth'],self.lineprops1['marker'],self.lineprops1['markersize'],self.lineprops1['fill'],\
        dummy,self.plot2,y2lo,y2hi,self.autoy2,self.smooth2,
        self.lineprops2['color'],self.lineprops2['linewidth'],self.lineprops2['marker'],self.lineprops2['markersize'],self.lineprops2['fill'],\
        dummy,self.plot3,y3lo,y3hi,self.autoy3,self.smooth3,
        self.lineprops3['color'],self.lineprops3['linewidth'],self.lineprops3['marker'],self.lineprops3['markersize'],self.lineprops3['fill'])=\
            WxQuery("Graph Settings",\
                [('wxnotebook','X Axis',None,None,None),
                 ('wxcombo','X axis',self.XAxisAllowed(),self.xaxis,'str'),
                 ("wxentry","Start",None,str(xlo),'str'),
                 ("wxentry","End",None,str(xhi),'str'),
                 ('wxcolor','Cursor color',None,self.cursorcolor,'str'),
                 ('wxspin','Cursor width','0|6|1',self.cursorwidth,'int'),

                 ('wxnotebook','Y1Axis',None,None,None),
                 ('wxcombo','Channel 1',self.YAxisAllowed(),self.plot1,'str'),
                 ('wxentry','Bottom',None,y1lo,'float'),
                 ('wxentry','Top',None,y1hi,'float'),
                 ('wxcheck','Auto Scale','-9|-8', self.autoy1,'bool'), #8
                 ('wxhscale','Smooth','1|12|1|1',self.smooth1,'int'),
                 ('wxcolor','Color',None,self.lineprops1['color'],'str'),
                 ('wxspin','Line width','0|12|1',self.lineprops1['linewidth'],'int'),
                 ('wxcombo','Marker','.|o|+|x|^|4|s|*|D',self.lineprops1['marker'],'str'),
                 ('wxspin','Marker size','0|12|1',self.lineprops1['markersize'],'int'),
                 ('wxcheck','Fill area',None,self.lineprops1['fill'],'bool'),

                 ('wxnotebook','Y2 Axis',None,None,None),
                 ('wxcombo','Channel 2',self.YAxisAllowed(),self.plot2,'str'),
                 ('wxentry','Bottom',None,y2lo,'float'),
                 ('wxentry','Top',None,y2hi,'float'),
                 ('wxcheck','Auto Scale','-20|-19', self.autoy2,'bool'),
                 ('wxhscale','Smooth','1|12|1|1',self.smooth2,'int'),
                 ('wxcolor','Color',None,self.lineprops2['color'],'str'),
                 ('wxspin','Line width','0|12|1',self.lineprops2['linewidth'],'int'),
                 ('wxcombo','Marker','.|o|+|x|^|4|s|*|D',self.lineprops2['marker'],'str'),
                 ('wxspin','Marker size','0|12|1',self.lineprops2['markersize'],'int'),
                 ('wxcheck','Fill area',None,self.lineprops2['fill'],'bool'),

                 ('wxnotebook','Y3 Axis',None,None,None),
                 ('wxcombo','Channel 3',self.YAxisAllowed(),self.plot3,'str'),
                 ('wxentry','Bottom',None,y3lo,'float'),
                 ('wxentry','Top',None,y3hi,'float'),
                 ('wxcheck','Auto Scale','-31|-30', self.autoy3,'bool'),
                 ('wxhscale','Smooth','1|12|1|1',self.smooth3,'int'),
                 ('wxcolor','Color',None,self.lineprops3['color'],'str'),
                 ('wxspin','Line width','0|12|1',self.lineprops3['linewidth'],'int'),
                 ('wxcombo','Marker','.|o|+|x|^|4|s|*|D',self.lineprops3['marker'],'str'),
                 ('wxspin','Marker size','0|12|1',self.lineprops3['markersize'],'int'),
                 ('wxcheck','Fill area',None,self.lineprops3['fill'],'bool')
                ])
        if self.xaxis == xaxis:
            xlo = max(self.x_to_num(xlo, False), self.x_min())
            xhi = min(self.x_to_num(xhi, False), self.x_max())
            self.ax1.set_xlim([xlo, xhi])
        else:  #time units have changed... don't bother and set to full x range
            self.xaxis = xaxis
            self.ax1.set_xlim([self.x_min(), self.x_max()])
        self.update_axis(self.ax1, self.plot1, y1lo, y1hi, self.autoy1,
                         self.lineprops1, self.smooth1)
        self.update_axis(self.ax2, self.plot2, y2lo, y2hi, self.autoy2,
                         self.lineprops2, self.smooth2)
        self.update_axis(self.ax3, self.plot3, y3lo, y3hi, self.autoy3,
                         self.lineprops3, self.smooth3)