class Viewer1DXRD(wx.Panel): ''' Frame for housing all 1D XRD viewer widgets ''' label='Viewer' def __init__(self,parent,owner=None,_larch=None): wx.Panel.__init__(self, parent) self.parent = parent self.owner = owner ## Default information self.data_name = [] self.xy_data = [] self.xy_plot = [] self.plotted_data = [] self.xy_scale = [] self.wavelength = None self.xlabel = 'q (A^-1)' self.xunits = ['q','d'] self.cif_name = [] self.cif_data = [] self.cif_plot = [] self.plotted_cif = [] self.x_for_zoom = None self.Panel1DViewer() ############################################## #### PANEL DEFINITIONS def Panel1DViewer(self): ''' Frame for housing all 1D XRD viewer widgets ''' leftside = self.LeftSidePanel(self) rightside = self.RightSidePanel(self) panel1D = wx.BoxSizer(wx.HORIZONTAL) panel1D.Add(leftside,flag=wx.ALL,border=10) panel1D.Add(rightside,proportion=1,flag=wx.EXPAND|wx.ALL,border=10) self.SetSizer(panel1D) def Toolbox(self,panel): ''' Frame for visual toolbox ''' tlbx = wx.StaticBox(self,label='PLOT TOOLBOX') vbox = wx.StaticBoxSizer(tlbx,wx.VERTICAL) ########################### ## X-Scale hbox_xaxis = wx.BoxSizer(wx.HORIZONTAL) ttl_xaxis = wx.StaticText(self, label='X-SCALE') self.ch_xaxis = wx.Choice(self,choices=self.xunits) self.ch_xaxis.Bind(wx.EVT_CHOICE, self.checkXaxis) hbox_xaxis.Add(ttl_xaxis, flag=wx.RIGHT, border=8) hbox_xaxis.Add(self.ch_xaxis, flag=wx.EXPAND, border=8) vbox.Add(hbox_xaxis, flag=wx.ALL, border=10) ########################### ## Y-Scale hbox_yaxis = wx.BoxSizer(wx.HORIZONTAL) ttl_yaxis = wx.StaticText(self, label='Y-SCALE') yscales = ['linear','log'] self.ch_yaxis = wx.Choice(self,choices=yscales) self.ch_yaxis.Bind(wx.EVT_CHOICE, None) hbox_yaxis.Add(ttl_yaxis, flag=wx.RIGHT, border=8) hbox_yaxis.Add(self.ch_yaxis, flag=wx.EXPAND, border=8) vbox.Add(hbox_yaxis, flag=wx.ALL, border=10) return vbox def DataBox(self,panel): ''' Frame for data toolbox ''' tlbx = wx.StaticBox(self,label='DATA TOOLBOX') vbox = wx.StaticBoxSizer(tlbx,wx.VERTICAL) ########################### ## DATA CHOICE self.ch_data = wx.Choice(self,choices=self.data_name) self.ch_data.Bind(wx.EVT_CHOICE, self.onSELECT) vbox.Add(self.ch_data, flag=wx.EXPAND|wx.ALL, border=8) #self.ttl_data = wx.StaticText(self, label='') #vbox.Add(self.ttl_data, flag=wx.EXPAND|wx.ALL, border=8) ########################### # self.ck_bkgd = wx.CheckBox(self,label='BACKGROUND') # self.ck_smth = wx.CheckBox(self,label='SMOOTHING') # # self.ck_bkgd.Bind(wx.EVT_CHECKBOX, None) # self.ck_smth.Bind(wx.EVT_CHECKBOX, None) # # vbox.Add(self.ck_bkgd, flag=wx.ALL, border=8) # vbox.Add(self.ck_smth, flag=wx.ALL, border=8) ########################### ## Scale hbox_scl = wx.BoxSizer(wx.HORIZONTAL) ttl_scl = wx.StaticText(self, label='SCALE Y TO:') self.entr_scale = wx.TextCtrl(self,wx.TE_PROCESS_ENTER) btn_scale = wx.Button(self,label='set') btn_scale.Bind(wx.EVT_BUTTON, self.normalize1Ddata) hbox_scl.Add(ttl_scl, flag=wx.RIGHT, border=8) hbox_scl.Add(self.entr_scale, flag=wx.RIGHT, border=8) hbox_scl.Add(btn_scale, flag=wx.RIGHT, border=8) vbox.Add(hbox_scl, flag=wx.BOTTOM|wx.TOP, border=8) ########################### ## Hide/show and reset hbox_btns = wx.BoxSizer(wx.HORIZONTAL) btn_hide = wx.Button(self,label='hide') btn_reset = wx.Button(self,label='reset') btn_rmv = wx.Button(self,label='remove') btn_hide.Bind(wx.EVT_BUTTON, self.hide1Ddata) btn_reset.Bind(wx.EVT_BUTTON, self.reset1Dscale) btn_rmv.Bind(wx.EVT_BUTTON, self.remove1Ddata) btn_hide.Disable() btn_rmv.Disable() hbox_btns.Add(btn_reset, flag=wx.ALL, border=10) hbox_btns.Add(btn_hide, flag=wx.ALL, border=10) hbox_btns.Add(btn_rmv, flag=wx.ALL, border=10) vbox.Add(hbox_btns, flag=wx.ALL, border=10) return vbox def AddPanel(self,panel): hbox = wx.BoxSizer(wx.HORIZONTAL) btn_data = wx.Button(panel,label='ADD NEW DATA SET') btn_data.Bind(wx.EVT_BUTTON, self.loadXYFILE) btn_cif = wx.Button(panel,label='ADD NEW CIF') btn_cif.Bind(wx.EVT_BUTTON, self.loadCIF) hbox.Add(btn_data, flag=wx.ALL, border=8) hbox.Add(btn_cif, flag=wx.ALL, border=8) return hbox def LeftSidePanel(self,panel): vbox = wx.BoxSizer(wx.VERTICAL) plttools = self.Toolbox(self) addbtns = self.AddPanel(self) dattools = self.DataBox(self) vbox.Add(plttools,flag=wx.ALL,border=10) vbox.Add(addbtns,flag=wx.ALL,border=10) vbox.Add(dattools,flag=wx.ALL,border=10) return vbox def RightSidePanel(self,panel): vbox = wx.BoxSizer(wx.VERTICAL) self.plot1DXRD(panel) btnbox = self.QuickButtons(panel) vbox.Add(self.plot1D,proportion=1,flag=wx.ALL|wx.EXPAND,border = 10) vbox.Add(btnbox,flag=wx.ALL|wx.ALIGN_RIGHT,border = 10) return vbox def QuickButtons(self,panel): buttonbox = wx.BoxSizer(wx.HORIZONTAL) btn_img = wx.Button(panel,label='SAVE FIGURE') btn_calib = wx.Button(panel,label='PLOT SETTINGS') btn_integ = wx.Button(panel,label='RESET PLOT') btn_img.Bind(wx.EVT_BUTTON, self.onSAVEfig) btn_calib.Bind(wx.EVT_BUTTON, self.onPLOTset) btn_integ.Bind(wx.EVT_BUTTON, self.onRESETplot) buttonbox.Add(btn_img, flag=wx.ALL, border=8) buttonbox.Add(btn_calib, flag=wx.ALL, border=8) buttonbox.Add(btn_integ, flag=wx.ALL, border=8) return buttonbox ############################################## #### PLOTPANEL FUNCTIONS def plot1DXRD(self,panel): self.plot1D = PlotPanel(panel,size=(1000, 500)) self.plot1D.messenger = self.owner.write_message ## Set defaults for plotting self.plot1D.set_ylabel('Intensity (a.u.)') self.plot1D.cursor_mode = 'zoom' ## trying to get this functionality into our gui ## mkak 2016.11.10 # interactive_legend().show() def onSAVEfig(self,event): self.plot1D.save_figure() def onPLOTset(self,event): self.plot1D.configure() def onRESETplot(self,event): self.plot1D.reset_config() ############################################## #### XRD PLOTTING FUNCTIONS def add1Ddata(self,x,y,name=None,cif=False,wavelength=None): plt_no = len(self.data_name) if cif: if name is None: name = 'cif %i' % plt_no else: name = 'cif: %s' % name else: if name is None: name = 'dataset %i' % plt_no else: name = 'data: %s' % name if wavelength is not None: self.addLAMBDA(wavelength) ## Add to data array lists self.data_name.append(name) self.xy_scale.append(max(y)) self.xy_data.extend([x,y]) ## redefine x,y based on scales self.xy_plot.extend([x,y]) ## Add to plot self.plotted_data.append(self.plot1D.oplot(x,y,label=name,show_legend=True))#,xlabel=self.xlabel)) ## Use correct x-axis units self.checkXaxis(None) self.ch_data.Set(self.data_name) self.ch_data.SetStringSelection(name) ## Update toolbox panel, scale all cif to 1000 if cif is True: self.entr_scale.SetValue('1000') self.normalize1Ddata(None) else: self.entr_scale.SetValue(str(self.xy_scale[plt_no])) def addLAMBDA(self,wavelength,units='m'): ## convert to units A if units == 'm': self.wavelength = wavelength*1e10 elif units == 'cm': self.wavelength = wavelength*1e8 elif units == 'mm': self.wavelength = wavelength*1e7 elif units == 'um': self.wavelength = wavelength*1e4 elif units == 'nm': self.wavelength = wavelength*1e1 else: ## units 'A' self.wavelength = wavelength self.xunits.append(u'2\u03B8') self.ch_xaxis.Set(self.xunits) def normalize1Ddata(self,event): plt_no = self.ch_data.GetSelection() self.xy_scale[plt_no] = float(self.entr_scale.GetValue()) if self.xy_scale[plt_no] <= 0: self.xy_scale[plt_no] = max(self.xy_data[(plt_no*2+1)]) self.entr_scale.SetValue(str(self.xy_scale[plt_no])) y = self.xy_data[(plt_no*2+1)] self.xy_plot[(plt_no*2+1)] = y/np.max(y) * self.xy_scale[plt_no] self.updatePLOT() def remove1Ddata(self,event): ## Needs pop up warning: "Do you really want to delete this data set from plotter? ## Current settings will not be saved." ## mkak 2016.11.10 plt_no = self.ch_data.GetSelection() print('EVENTUALLY, button will remove plot: %s' % self.data_name[plt_no]) ## removing name from list works... do not activate till rest is working ## mkak 2016.11.10 # self.data_name.remove(self.data_name[plt_no]) # self.ch_data.Set(self.data_name) def hide1Ddata(self,event): plt_no = self.ch_data.GetSelection() print('EVENTUALLY, button will hide plot: %s' % self.data_name[plt_no]) def onSELECT(self,event): data_str = self.ch_data.GetString(self.ch_data.GetSelection()) # self.ttl_data.SetLabel('SELECTED: %s' % data_str) plt_no = self.ch_data.GetSelection() self.entr_scale.SetValue(str(self.xy_scale[plt_no])) def checkXaxis(self, event): if self.ch_xaxis.GetSelection() == 2: for plt_no in range(len(self.plotted_data)): self.xy_plot[plt_no*2] = calc_q_to_2th(self.xy_data[plt_no*2],self.wavelength) elif self.ch_xaxis.GetSelection() == 1: for plt_no in range(len(self.plotted_data)): self.xy_plot[plt_no*2] = calc_q_to_d(self.xy_data[plt_no*2]) else: for plt_no in range(len(self.plotted_data)): self.xy_plot[plt_no*2] = self.xy_data[plt_no*2] if self.ch_xaxis.GetSelection() == 2: self.xlabel = r'$2\Theta$'+r' $(^\circ)$' elif self.ch_xaxis.GetSelection() == 1: self.xlabel = 'd ($\AA$)' else: self.xlabel = 'q (1/$\AA$)' self.plot1D.set_xlabel(self.xlabel) self.updatePLOT() def updatePLOT(self): xmax,xmin,ymax,ymin = None,0,None,0 if len(self.plotted_data) > 0: for plt_no in range(len(self.plotted_data)): i = plt_no*2 j = i+1 x = self.xy_plot[i] y = self.xy_plot[j] if xmax is None or xmax < max(x): xmax = max(x) if xmin > min(x): xmin = min(x) if ymax is None or ymax < max(y): ymax = max(y) if ymin > min(y): ymin = min(y) self.plot1D.update_line(plt_no,x,y) self.unzoom_all() self.plot1D.canvas.draw() if self.ch_xaxis.GetSelection() == 1: xmax = 5 self.plot1D.set_xylims([xmin, xmax, ymin, ymax]) def reset1Dscale(self,event): plt_no = self.ch_data.GetSelection() self.xy_plot[(plt_no*2+1)] = self.xy_data[(plt_no*2+1)] self.plot1D.update_line(plt_no,self.xy_plot[(plt_no*2)], self.xy_plot[(plt_no*2+1)]) self.plot1D.canvas.draw() self.unzoom_all() self.updatePLOT() self.xy_scale[plt_no] = max(self.xy_data[(plt_no*2+1)]) self.entr_scale.SetValue(str(self.xy_scale[plt_no])) ####### BEGIN ####### ## THIS IS DIRECTLY FROM XRDDISPLAY.PY ## mkak 2016.11.11 def unzoom_all(self, event=None): xmid, xrange, xmin, xmax = self._get1Dlims() self._set_xview(xmin, xmax) self.xview_range = None def _get1Dlims(self): xmin, xmax = self.plot1D.axes.get_xlim() xrange = xmax-xmin xmid = (xmax+xmin)/2.0 if self.x_for_zoom is not None: xmid = self.x_for_zoom return (xmid, xrange, xmin, xmax) def _set_xview(self, x1, x2, keep_zoom=False, pan=False): xmin,xmax = self.abs_limits() xrange = x2-x1 x1 = max(xmin,x1) x2 = min(xmax,x2) if pan: if x2 == xmax: x1 = x2-xrange elif x1 == xmin: x2 = x1+xrange if not keep_zoom: self.x_for_zoom = (x1+x2)/2.0 self.plot1D.axes.set_xlim((x1, x2)) self.xview_range = [x1, x2] self.plot1D.canvas.draw() def abs_limits(self): if len(self.data_name) > 0: xmin, xmax = self.xy_plot[0].min(), self.xy_plot[0].max() return xmin,xmax ####### END ####### ############################################## #### XRD FILE OPENING/SAVING def loadXYFILE(self,event): wildcards = 'XRD data file (*.xy)|*.xy|All files (*.*)|*.*' dlg = wx.FileDialog(self, message='Choose 1D XRD data file', defaultDir=os.getcwd(), wildcard=wildcards, style=wx.FD_OPEN) path, read = None, False if dlg.ShowModal() == wx.ID_OK: read = True path = dlg.GetPath().replace('\\', '/') dlg.Destroy() if read: try: x,y = xy_file_reader(path) self.add1Ddata(x,y,name=os.path.split(path)[-1]) except: print('incorrect xy file format: %s' % os.path.split(path)[-1]) def saveXYFILE(self,event): wildcards = 'XRD data file (*.xy)|*.xy|All files (*.*)|*.*' dlg = wx.FileDialog(self, 'Save data as...', defaultDir=os.getcwd(), wildcard=wildcards, style=wx.SAVE|wx.OVERWRITE_PROMPT) path, save = None, False if dlg.ShowModal() == wx.ID_OK: save = True path = dlg.GetPath().replace('\\', '/') dlg.Destroy() if save: ## mkak 2016.11.16 print('need to write something to save data - like pyFAI does?') def loadCIF(self,event): wildcards = 'XRD cifile (*.cif)|*.cif|All files (*.*)|*.*' dlg = wx.FileDialog(self, message='Choose CIF', defaultDir=os.getcwd(), wildcard=wildcards, style=wx.FD_OPEN) path, read = None, False if dlg.ShowModal() == wx.ID_OK: read = True path = dlg.GetPath().replace('\\', '/') dlg.Destroy() if read: cifile = os.path.split(path)[-1] try: cif = xu.materials.Crystal.fromCIF(path) except: print('incorrect file format: %s' % os.path.split(path)[-1]) return ## generate hkl list hkllist = [] maxhkl = 8 for i in range(-maxhkl,maxhkl+1): for j in range(-maxhkl,maxhkl+1): for k in range(-maxhkl,maxhkl+1): if i+j+k > 0: # as long as h,k,l all positive, eliminates 0,0,0 hkllist.append([i,j,k]) hc = constants.value(u'Planck constant in eV s') * \ constants.value(u'speed of light in vacuum') * 1e-3 ## units: keV-m if self.wavelength is not None: qlist = cif.Q(hkllist) Flist = cif.StructureFactorForQ(qlist,(hc/(self.wavelength*(1e-10))*1e3)) Fall = [] qall = [] hklall = [] for i,hkl in enumerate(hkllist): if np.abs(Flist[i]) > 0.01: Fadd = np.abs(Flist[i]) qadd = np.linalg.norm(qlist[i]) if qadd not in qall and qadd < 6: Fall.extend((0,Fadd,0)) qall.extend((qadd,qadd,qadd)) if np.shape(Fall)[0] > 0: Fall = np.array(Fall) qall = np.array(qall) self.add1Ddata(qall,Fall,name=os.path.split(path)[-1],cif=True) else: print('Could not calculate real structure factors.') else: print('Wavelength/energy must be specified for structure factor calculations.') def openPONI(self,event): wildcards = 'pyFAI calibration file (*.poni)|*.poni|All files (*.*)|*.*' dlg = wx.FileDialog(self, message='Choose pyFAI calibration file', defaultDir=os.getcwd(), wildcard=wildcards, style=wx.FD_OPEN) path, read = None, False if dlg.ShowModal() == wx.ID_OK: read = True path = dlg.GetPath().replace('\\', '/') dlg.Destroy() if read: try: print('Loading calibration file: %s' % path) ai = pyFAI.load(path) except: print('Not recognized as a pyFAI calibration file.') return self.addLAMBDA(ai._wavelength,units='m') def setLAMBDA(self,event): dlg = SetLambdaDialog() path, okay = None, False if dlg.ShowModal() == wx.ID_OK: okay = True wavelength = dlg.wavelength dlg.Destroy() if okay: self.addLAMBDA(wavelength,units='A')
class Fitting1DXRD(wx.Panel): ''' Frame for housing all 1D XRD fitting widgets ''' label='Fitting' def __init__(self,parent,owner=None,_larch=None): wx.Panel.__init__(self, parent) self.parent = parent self.owner = owner ## Default information self.xlabel = 'q (A^-1)' self.xunits = ['q','d'] self.Panel1DFitting() ############################################## #### PANEL DEFINITIONS def Panel1DFitting(self): ''' Frame for housing all 1D XRD viewer widgets ''' leftside = self.LeftSidePanel(self) rightside = self.RightSidePanel(self) panel1D = wx.BoxSizer(wx.HORIZONTAL) panel1D.Add(leftside,flag=wx.ALL,border=10) panel1D.Add(rightside,proportion=1,flag=wx.EXPAND|wx.ALL,border=10) self.SetSizer(panel1D) def Toolbox(self,panel): ''' Frame for visual toolbox ''' tlbx = wx.StaticBox(self,label='PLOT TOOLBOX') vbox = wx.StaticBoxSizer(tlbx,wx.VERTICAL) ########################### ## X-Scale hbox_xaxis = wx.BoxSizer(wx.HORIZONTAL) ttl_xaxis = wx.StaticText(self, label='X-SCALE') self.ch_xaxis = wx.Choice(self,choices=self.xunits) self.ch_xaxis.Bind(wx.EVT_CHOICE, self.checkXaxis) hbox_xaxis.Add(ttl_xaxis, flag=wx.RIGHT, border=8) hbox_xaxis.Add(self.ch_xaxis, flag=wx.EXPAND, border=8) vbox.Add(hbox_xaxis, flag=wx.ALL, border=10) ########################### ## Y-Scale hbox_yaxis = wx.BoxSizer(wx.HORIZONTAL) ttl_yaxis = wx.StaticText(self, label='Y-SCALE') yscales = ['linear','log'] self.ch_yaxis = wx.Choice(self,choices=yscales) self.ch_yaxis.Bind(wx.EVT_CHOICE, None) hbox_yaxis.Add(ttl_yaxis, flag=wx.RIGHT, border=8) hbox_yaxis.Add(self.ch_yaxis, flag=wx.EXPAND, border=8) vbox.Add(hbox_yaxis, flag=wx.ALL, border=10) return vbox def LeftSidePanel(self,panel): vbox = wx.BoxSizer(wx.VERTICAL) plttools = self.Toolbox(self) vbox.Add(plttools,flag=wx.ALL,border=10) return vbox def RightSidePanel(self,panel): vbox = wx.BoxSizer(wx.VERTICAL) self.plot1DXRD(panel) btnbox = self.QuickButtons(panel) vbox.Add(self.plot1D,proportion=1,flag=wx.ALL|wx.EXPAND,border = 10) vbox.Add(btnbox,flag=wx.ALL|wx.ALIGN_RIGHT,border = 10) return vbox def QuickButtons(self,panel): buttonbox = wx.BoxSizer(wx.HORIZONTAL) btn_img = wx.Button(panel,label='SAVE FIGURE') btn_calib = wx.Button(panel,label='PLOT SETTINGS') btn_integ = wx.Button(panel,label='RESET PLOT') btn_img.Bind(wx.EVT_BUTTON, self.onSAVEfig) btn_calib.Bind(wx.EVT_BUTTON, self.onPLOTset) btn_integ.Bind(wx.EVT_BUTTON, self.onRESETplot) buttonbox.Add(btn_img, flag=wx.ALL, border=8) buttonbox.Add(btn_calib, flag=wx.ALL, border=8) buttonbox.Add(btn_integ, flag=wx.ALL, border=8) return buttonbox ############################################## #### PLOTPANEL FUNCTIONS def plot1DXRD(self,panel): self.plot1D = PlotPanel(panel,size=(1000, 500)) self.plot1D.messenger = self.owner.write_message ## Set defaults for plotting self.plot1D.set_ylabel('Intensity (a.u.)') self.plot1D.cursor_mode = 'zoom' ## trying to get this functionality into our gui ## mkak 2016.11.10 # interactive_legend().show() def onSAVEfig(self,event): self.plot1D.save_figure() def onPLOTset(self,event): self.plot1D.configure() def onRESETplot(self,event): self.plot1D.reset_config() def checkXaxis(self, event): if self.ch_xaxis.GetSelection() == 2: for plt_no in range(len(self.plotted_data)): self.xy_plot[plt_no*2] = calc_q_to_2th(self.xy_data[plt_no*2],self.wavelength) elif self.ch_xaxis.GetSelection() == 1: for plt_no in range(len(self.plotted_data)): self.xy_plot[plt_no*2] = calc_q_to_d(self.xy_data[plt_no*2]) else: for plt_no in range(len(self.plotted_data)): self.xy_plot[plt_no*2] = self.xy_data[plt_no*2] if self.ch_xaxis.GetSelection() == 2: self.xlabel = r'$2\Theta$'+r' $(^\circ)$' elif self.ch_xaxis.GetSelection() == 1: self.xlabel = 'd ($\AA$)' else: self.xlabel = 'q (1/$\AA$)' self.plot1D.set_xlabel(self.xlabel) self.updatePLOT() def updatePLOT(self): xmax,xmin,ymax,ymin = None,0,None,0 if len(self.plotted_data) > 0: for plt_no in range(len(self.plotted_data)): i = plt_no*2 j = i+1 x = self.xy_plot[i] y = self.xy_plot[j] if xmax is None or xmax < max(x): xmax = max(x) if xmin > min(x): xmin = min(x) if ymax is None or ymax < max(y): ymax = max(y) if ymin > min(y): ymin = min(y) self.plot1D.update_line(plt_no,x,y) self.unzoom_all() self.plot1D.canvas.draw() if self.ch_xaxis.GetSelection() == 1: xmax = 5 self.plot1D.set_xylims([xmin, xmax, ymin, ymax]) def reset1Dscale(self,event): plt_no = self.ch_data.GetSelection() self.xy_plot[(plt_no*2+1)] = self.xy_data[(plt_no*2+1)] self.plot1D.update_line(plt_no,self.xy_plot[(plt_no*2)], self.xy_plot[(plt_no*2+1)]) self.plot1D.canvas.draw() self.unzoom_all() self.updatePLOT() self.xy_scale[plt_no] = max(self.xy_data[(plt_no*2+1)]) self.entr_scale.SetValue(str(self.xy_scale[plt_no])) ####### BEGIN ####### ## THIS IS DIRECTLY FROM XRDDISPLAY.PY ## mkak 2016.11.11 def unzoom_all(self, event=None): xmid, xrange, xmin, xmax = self._get1Dlims() self._set_xview(xmin, xmax) self.xview_range = None def _get1Dlims(self): xmin, xmax = self.plot1D.axes.get_xlim() xrange = xmax-xmin xmid = (xmax+xmin)/2.0 if self.x_for_zoom is not None: xmid = self.x_for_zoom return (xmid, xrange, xmin, xmax) def _set_xview(self, x1, x2, keep_zoom=False, pan=False): xmin,xmax = self.abs_limits() xrange = x2-x1 x1 = max(xmin,x1) x2 = min(xmax,x2) if pan: if x2 == xmax: x1 = x2-xrange elif x1 == xmin: x2 = x1+xrange if not keep_zoom: self.x_for_zoom = (x1+x2)/2.0 self.plot1D.axes.set_xlim((x1, x2)) self.xview_range = [x1, x2] self.plot1D.canvas.draw() def abs_limits(self): if len(self.data_name) > 0: xmin, xmax = self.xy_plot[0].min(), self.xy_plot[0].max() return xmin,xmax