source: sasview/guiframe/local_perspectives/plotting/Plotter2D.py @ f7a5c7e

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since f7a5c7e was 88ca6db, checked in by Gervaise Alina <gervyh@…>, 15 years ago

remove approprite button in the toolbar for 2 d

  • Property mode set to 100644
File size: 20.7 KB
RevLine 
[1bf33c1]1"""
2This software was developed by the University of Tennessee as part of the
3Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
4project funded by the US National Science Foundation.
5
6See the license text in license.txt
7
8copyright 2008, University of Tennessee
9"""
10
11
12import wx
[ea290ee]13import sys, math
[0d9dae8]14import pylab
15
[1bf33c1]16import danse.common.plottools
17from danse.common.plottools.PlotPanel import PlotPanel
[4ac8556]18from danse.common.plottools.plottables import Graph
[0bd2cd8]19from sans.guicomm.events import EVT_NEW_PLOT
[0d9dae8]20from sans.guicomm.events import EVT_SLICER_PARS
21from sans.guicomm.events import StatusEvent ,NewPlotEvent,SlicerEvent
22from sans.guiframe.utils import PanelMenu
[1bf33c1]23from binder import BindArtist
24from Plotter1D import ModelPanel1D
[4ac8556]25 
26from sans.guiframe.dataFitting import Data1D
[0d9dae8]27(InternalEvent, EVT_INTERNAL)   = wx.lib.newevent.NewEvent()
28
[1bf33c1]29
[0d9dae8]30
31DEFAULT_QMAX = 0.05
[1bf33c1]32DEFAULT_QSTEP = 0.001
33DEFAULT_BEAM = 0.005
[ef0c170]34BIN_WIDTH = 1.0
[ac8671e]35from danse.common.plottools.toolbar import NavigationToolBar
36class NavigationToolBar2D(NavigationToolBar):
37    def __init__(self, canvas, parent=None):
38        NavigationToolBar.__init__(self, canvas=canvas, parent=parent)
39       
40    def delete_option(self):
41        """
42            remove default toolbar item
43        """
44        #delete reset button
45        self.DeleteToolByPos(0) 
46        #delete dragging
[88ca6db]47        self.DeleteToolByPos(2) 
[ac8671e]48        #delete unwanted button that configures subplot parameters
49        self.DeleteToolByPos(4)
50       
51    def add_option(self):
52        """
53            add item to the toolbar
54        """
55        #add print button
56        id_print = wx.NewId()
57        print_bmp =  wx.ArtProvider.GetBitmap(wx.ART_PRINT, wx.ART_TOOLBAR)
58        self.AddSimpleTool(id_print, print_bmp,
59                           'Print', 'Activate printing')
60        wx.EVT_TOOL(self, id_print, self.on_print)
61       
62       
[0d9dae8]63
[ac8671e]64class ModelPanel2D(ModelPanel1D):
[1bf33c1]65    """
66        Plot panel for use with the GUI manager
67    """
68   
69    ## Internal name for the AUI manager
70    window_name = "plotpanel"
71    ## Title to appear on top of the window
72    window_caption = "Plot Panel"
73    ## Flag to tell the GUI manager that this panel is not
74    #  tied to any perspective
75    ALWAYS_ON = True
76    ## Group ID
77    group_id = None
78   
79   
80    def __init__(self, parent, id = -1,data2d=None, color = None,\
81        dpi = None, style = wx.NO_FULL_REPAINT_ON_RESIZE, **kwargs):
82        """
83            Initialize the panel
84        """
85        ModelPanel1D.__init__(self, parent, id = id, style = style, **kwargs)
86       
87        ## Reference to the parent window
88        self.parent = parent
[6c0568b]89        ## Dictionary containing Plottables
[1bf33c1]90        self.plots = {}
[6c0568b]91        ## Save reference of the current plotted
92        self.data2D = data2d
[1bf33c1]93        ## Unique ID (from gui_manager)
94        self.uid = None
95        ## Action IDs for internal call-backs
96        self.action_ids = {}
[6c0568b]97        ## Create Artist and bind it
[1bf33c1]98        self.connect = BindArtist(self.subplot.figure)
[6c0568b]99        ## Beam stop
[1bf33c1]100        self.beamstop_radius = DEFAULT_BEAM
[6c0568b]101        ## to set the order of lines drawn first.
[f15ed33]102        self.slicer_z = 5
[6c0568b]103        ## Reference to the current slicer
[1bf33c1]104        self.slicer = None
[6c0568b]105        ## event to send slicer info
[d468daa]106        self.Bind(EVT_INTERNAL, self._onEVT_INTERNAL)
[1bf33c1]107       
[6c0568b]108        self.axes_frozen = False
109        ## panel that contains result from slicer motion (ex: Boxsum info)
[54cc36a]110        self.panel_slicer=None
[8dfdd20]111       
[1bf33c1]112        ## Graph       
113        self.graph = Graph()
114        self.graph.xaxis("\\rm{Q}", 'A^{-1}')
115        self.graph.yaxis("\\rm{Intensity} ","cm^{-1}")
116        self.graph.render(self)
[8dfdd20]117        ## store default value of zmin and zmax
118        self.default_zmin_ctl = self.zmin_2D
119        self.default_zmax_ctl = self.zmax_2D
[ac8671e]120       
121    def add_toolbar(self):
122        """
123            add toolbar
124        """
125        self.enable_toolbar = True
126       
127        self.toolbar = NavigationToolBar2D(parent=self,canvas=self.canvas)
128        self.toolbar.Realize()
129     
130        # On Windows platform, default window size is incorrect, so set
131        # toolbar width to figure width.
132        tw, th = self.toolbar.GetSizeTuple()
133        fw, fh = self.canvas.GetSizeTuple()
134     
135        self.toolbar.SetSize(wx.Size(fw, th))
136        self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
[0d9dae8]137       
[ac8671e]138        # update the axes menu on the toolbar
139        self.toolbar.update()
140         
[1bf33c1]141    def _onEVT_1DREPLOT(self, event):
142        """
143            Data is ready to be displayed
[4b91fd1]144           
145            #TODO: this name should be changed to something more appropriate
146            # Don't forget that changing this name will mean changing code
147            # in plotting.py
148             
[1bf33c1]149            @param event: data event
150        """
[6c0568b]151        ## Update self.data2d with the current plot
152        self.data2D = event.plot
[15550f4]153       
[1bf33c1]154        #TODO: Check for existence of plot attribute
[6c0568b]155       
[1bf33c1]156        # Check whether this is a replot. If we ask for a replot
157        # and the plottable no longer exists, ignore the event.
158        if hasattr(event, "update") and event.update==True \
159            and event.plot.name not in self.plots.keys():
160            return
[ab8f936]161       
[1bf33c1]162        if hasattr(event, "reset"):
163            self._reset()
164        is_new = True
165        if event.plot.name in self.plots.keys():
166            # Check whether the class of plottable changed
167            if not event.plot.__class__==self.plots[event.plot.name].__class__:
[ab8f936]168                #overwrite a plottable using the same name
[1bf33c1]169                self.graph.delete(self.plots[event.plot.name])
170            else:
[ab8f936]171                # plottable is already draw on the panel
[1bf33c1]172                is_new = False
[ab8f936]173           
174        if is_new:
175            # a new plottable overwrites a plotted one  using the same id
176            for plottable in self.plots.itervalues():
[e48a62e]177                if hasattr(event.plot,"id"):
178                    if event.plot.id==plottable.id :
179                        self.graph.delete(plottable)
[ab8f936]180           
181            self.plots[event.plot.name] = event.plot
182            self.graph.add(self.plots[event.plot.name])
183        else:
[4b91fd1]184            # Update the plottable with the new data
185           
186            #TODO: we should have a method to do this,
187            #      something along the lines of:
188            #      plottable1.update_data_from_plottable(plottable2)
189           
190            self.plots[event.plot.name].xmin = event.plot.xmin
191            self.plots[event.plot.name].xmax = event.plot.xmax
192            self.plots[event.plot.name].ymin = event.plot.ymin
193            self.plots[event.plot.name].ymax = event.plot.ymax
194            self.plots[event.plot.name].data = event.plot.data
[20b6760]195            self.plots[event.plot.name].qx_data = event.plot.qx_data
196            self.plots[event.plot.name].qy_data = event.plot.qy_data
[4b91fd1]197            self.plots[event.plot.name].err_data = event.plot.err_data
[ac9a5f6]198            # update qmax with the new xmax of data plotted
199            self.qmax= event.plot.xmax
[4b91fd1]200           
[ac9a5f6]201        self.slicer= None
[1bf33c1]202        # Check axis labels
203        #TODO: Should re-factor this
[6c0568b]204        ## render the graph with its new content
[7fff5cd]205               
206        #data2D: put 'Pixel (Number)' for axis title and unit in case of having no detector info and none in _units
207        if len(self.data2D.detector) < 1: 
208            if len(event.plot._xunit)< 1 and len(event.plot._yunit) < 1:
[b03deea]209                event.plot._xaxis = '\\rm{x}'
210                event.plot._yaxis = '\\rm{y}'
211                event.plot._xunit = 'pixel'
212                event.plot._yunit = 'pixel'
[7fff5cd]213
[1bf33c1]214        self.graph.xaxis(event.plot._xaxis, event.plot._xunit)
215        self.graph.yaxis(event.plot._yaxis, event.plot._yunit)
[0690e1d]216        self.graph.title(self.data2D.name)
[1bf33c1]217        self.graph.render(self)
218        self.subplot.figure.canvas.draw_idle()
[8dfdd20]219        ## store default value of zmin and zmax
220        self.default_zmin_ctl = self.zmin_2D
221        self.default_zmax_ctl = self.zmax_2D
[1bf33c1]222
223
224    def onContextMenu(self, event):
225        """
226            2D plot context menu
227            @param event: wx context event
228        """
[15550f4]229       
[1bf33c1]230        slicerpop = PanelMenu()
231        slicerpop.set_plots(self.plots)
232        slicerpop.set_graph(self.graph)
[9a585d0]233             
234        id = wx.NewId()
235        slicerpop.Append(id, '&Save image')
236        wx.EVT_MENU(self, id, self.onSaveImage)
237       
238        id = wx.NewId()
239        slicerpop.Append(id,'&Print image', 'Print image ')
240        wx.EVT_MENU(self, id, self.onPrint)
241       
[1ce365f8]242        id = wx.NewId()
[18eba35]243        slicerpop.Append(id,'&Print Preview', 'image preview for print')
[1ce365f8]244        wx.EVT_MENU(self, id, self.onPrinterPreview)
245       
[9a585d0]246        slicerpop.AppendSeparator()
[7fff5cd]247        if len(self.data2D.detector) == 1:       
[0e13148]248           
249            item_list = self.parent.get_context_menu(self.graph)
250            if (not item_list==None) and (not len(item_list)==0):
251                   
252                    for item in item_list:
253                        try:
254                            id = wx.NewId()
255                            slicerpop.Append(id, item[0], item[1])
256                            wx.EVT_MENU(self, id, item[2])
257                        except:
258                            wx.PostEvent(self.parent, StatusEvent(status=\
259                            "ModelPanel1D.onContextMenu: bad menu item  %s"%sys.exc_value))
260                            pass
261                    slicerpop.AppendSeparator()
262           
[15550f4]263            id = wx.NewId()
264            slicerpop.Append(id, '&Perform circular average')
265            wx.EVT_MENU(self, id, self.onCircular) 
266           
267            id = wx.NewId()
268            slicerpop.Append(id, '&Sector [Q view]')
269            wx.EVT_MENU(self, id, self.onSectorQ) 
270           
271            id = wx.NewId()
272            slicerpop.Append(id, '&Annulus [Phi view ]')
273            wx.EVT_MENU(self, id, self.onSectorPhi) 
274           
[92c2345]275            id = wx.NewId()
[15550f4]276            slicerpop.Append(id, '&Box Sum')
277            wx.EVT_MENU(self, id, self.onBoxSum) 
[6c0568b]278           
[15550f4]279            id = wx.NewId()
280            slicerpop.Append(id, '&Box averaging in Qx')
281            wx.EVT_MENU(self, id, self.onBoxavgX) 
282           
283            id = wx.NewId()
284            slicerpop.Append(id, '&Box averaging in Qy')
285            wx.EVT_MENU(self, id, self.onBoxavgY) 
286           
287            if self.slicer !=None :
[eba08f1a]288                id = wx.NewId()
[15550f4]289                slicerpop.Append(id, '&Clear slicer')
290                wx.EVT_MENU(self, id,  self.onClearSlicer) 
[6c0568b]291               
[15550f4]292                if self.slicer.__class__.__name__ !="BoxSum":
293                    id = wx.NewId()
294                    slicerpop.Append(id, '&Edit Slicer Parameters')
295                    wx.EVT_MENU(self, id, self._onEditSlicer) 
296                   
297            slicerpop.AppendSeparator() 
[0e13148]298           
299        id = wx.NewId()
300        slicerpop.Append(id, '&Detector Parameters')
301        wx.EVT_MENU(self, id, self._onEditDetector) 
302       
[9a585d0]303       
[1bf33c1]304        id = wx.NewId()
305        slicerpop.Append(id, '&Toggle Linear/Log scale')
306        wx.EVT_MENU(self, id, self._onToggleScale) 
[d468daa]307                 
[1bf33c1]308        pos = event.GetPosition()
309        pos = self.ScreenToClient(pos)
310        self.PopupMenu(slicerpop, pos)
[8bd764d]311   
[6c0568b]312   
[ea290ee]313    def _onEditDetector(self, event):
[6d920cd]314        """
[6c0568b]315            Allow to view and edits  detector parameters
316            @param event: wx.menu event
[6d920cd]317        """
[6c0568b]318       
[ea290ee]319        import detector_dialog
[8dfdd20]320       
321        dialog = detector_dialog.DetectorDialog(self, -1,base=self.parent,
322                       reset_zmin_ctl =self.default_zmin_ctl,
323                       reset_zmax_ctl = self.default_zmax_ctl,cmap=self.cmap)
[6c0568b]324        ## info of current detector and data2D
[ea290ee]325        xnpts = len(self.data2D.x_bins)
326        ynpts = len(self.data2D.y_bins)
327        xmax = max(self.data2D.xmin, self.data2D.xmax)
328        ymax = max(self.data2D.ymin, self.data2D.ymax)
329        qmax = math.sqrt(math.pow(xmax,2)+math.pow(ymax,2))
330        beam = self.data2D.xmin
[e50f15b]331     
[6c0568b]332        ## set dialog window content
[ea290ee]333        dialog.setContent(xnpts=xnpts,ynpts=ynpts,qmax=qmax,
334                           beam=self.data2D.xmin,
335                           zmin = self.zmin_2D,
336                          zmax = self.zmax_2D)
337        if dialog.ShowModal() == wx.ID_OK:
338            evt = dialog.getContent()
339            self.zmin_2D = evt.zmin
340            self.zmax_2D = evt.zmax
[8dfdd20]341            self.cmap= evt.cmap
[ea290ee]342       
343        dialog.Destroy()
[6c0568b]344        ## Redraw the current image
[ea290ee]345        self.image(data= self.data2D.data,
[20b6760]346                   qx_data=self.data2D.qx_data,
347                   qy_data=self.data2D.qy_data,
[ea290ee]348                   xmin= self.data2D.xmin,
349                   xmax= self.data2D.xmax,
350                   ymin= self.data2D.ymin,
351                   ymax= self.data2D.ymax,
352                   zmin= self.zmin_2D,
353                   zmax= self.zmax_2D,
[8dfdd20]354                   cmap= self.cmap,
[e50f15b]355                   color=0,symbol=0,label=self.data2D.name)#'data2D')
[ea290ee]356        self.subplot.figure.canvas.draw_idle()
[1bf33c1]357       
[6c0568b]358       
359 
[1bf33c1]360    def freeze_axes(self):
361        self.axes_frozen = True
362       
363    def thaw_axes(self):
364        self.axes_frozen = False
365       
366    def onMouseMotion(self,event):
367        pass
368    def onWheel(self, event):
[6c0568b]369        pass 
370     
[1bf33c1]371    def update(self, draw=True):
372        """
373            Respond to changes in the model by recalculating the
374            profiles and resetting the widgets.
375        """
376        self.draw()
377       
378       
379    def _getEmptySlicerEvent(self):
[6c0568b]380        """
381            create an empty slicervent
382        """
[1bf33c1]383        return SlicerEvent(type=None,
384                           params=None,
385                           obj_class=None)
386    def _onEVT_INTERNAL(self, event):
387        """
[6c0568b]388            Draw the slicer
389            @param event: wx.lib.newevent (SlicerEvent) containing slicer
390            parameter
[1bf33c1]391        """
392        self._setSlicer(event.slicer)
393           
394    def _setSlicer(self, slicer):
[6c0568b]395        """
396            Clear the previous slicer and create a new one.Post an internal
397            event.
398            @param slicer: slicer class to create
399        """
[1bf33c1]400       
[6c0568b]401        ## Clear current slicer
[1bf33c1]402        if not self.slicer == None: 
403            self.slicer.clear()           
[6c0568b]404        ## Create a new slicer   
[1bf33c1]405        self.slicer_z += 1
406        self.slicer = slicer(self, self.subplot, zorder=self.slicer_z)
[240c805]407        self.subplot.set_ylim(self.data2D.ymin, self.data2D.ymax)
408        self.subplot.set_xlim(self.data2D.xmin, self.data2D.xmax)
[6c0568b]409        ## Draw slicer
[1bf33c1]410        self.update()
411        self.slicer.update()
[6c0568b]412        wx.PostEvent(self.parent, StatusEvent(status=\
413                        "Plotter2D._setSlicer  %s"%self.slicer.__class__.__name__))
[1bf33c1]414        # Post slicer event
415        event = self._getEmptySlicerEvent()
416        event.type = self.slicer.__class__.__name__
[54cc36a]417       
[1bf33c1]418        event.obj_class = self.slicer.__class__
419        event.params = self.slicer.get_params()
[d468daa]420        wx.PostEvent(self, event)
[1bf33c1]421
[6c0568b]422
[1bf33c1]423    def onCircular(self, event):
424        """
425            perform circular averaging on Data2D
[6c0568b]426            @param event: wx.menu event
[1bf33c1]427        """
428       
429        from DataLoader.manipulations import CircularAverage
[6c0568b]430        ## compute the maximum radius of data2D
[216efab]431        self.qmax= max(math.fabs(self.data2D.xmax),math.fabs(self.data2D.xmin))
432        self.ymax=max(math.fabs(self.data2D.ymax),math.fabs(self.data2D.ymin))
433        self.radius= math.sqrt( math.pow(self.qmax,2)+math.pow(self.ymax,2)) 
[6c0568b]434        ##Compute beam width
[8f584c9]435        bin_width = (self.qmax +self.qmax)/100
[6c0568b]436        ## Create data1D circular average of data2D
[c73d871]437        Circle = CircularAverage( r_min=0, r_max=self.radius, bin_width=bin_width)
[1bf33c1]438        circ = Circle(self.data2D)
[6c0568b]439       
[1bf33c1]440        from sans.guiframe.dataFitting import Data1D
441        if hasattr(circ,"dxl"):
442            dxl= circ.dxl
443        else:
444            dxl= None
445        if hasattr(circ,"dxw"):
446            dxw= circ.dxw
447        else:
448            dxw= None
[ef0c170]449       
[4ac8556]450        new_plot = Data1D(x=circ.x,y=circ.y,dy=circ.dy)
451        new_plot.dxl=dxl
452        new_plot.dxw=dxw
[1bf33c1]453        new_plot.name = "Circ avg "+ self.data2D.name
454        new_plot.source=self.data2D.source
[50cbace]455        #new_plot.info=self.data2D.info
[1bf33c1]456        new_plot.interactive = True
457        new_plot.detector =self.data2D.detector
[6c0568b]458        ## If the data file does not tell us what the axes are, just assume...
[8f584c9]459        new_plot.xaxis("\\rm{Q}","A^{-1}")
[1bf33c1]460        new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
461        new_plot.group_id = "Circ avg "+ self.data2D.name
[8b30e62]462        new_plot.id = "Circ avg "+ self.data2D.name
[70cf5d3]463        new_plot.is_data= True
[6c0568b]464       
[1bf33c1]465        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title=new_plot.name))
[ef0c170]466       
[6c0568b]467       
[1bf33c1]468    def _onEditSlicer(self, event):
[6c0568b]469        """
470            Is available only when a slicer is drawn.Create a dialog
471            window where the user can enter value to reset slicer
472            parameters.
473            @param event: wx.menu event
474        """
[1bf33c1]475        if self.slicer !=None:
476            from SlicerParameters import SlicerParameterPanel
[4f8a00c]477            dialog = SlicerParameterPanel(self, -1, "Slicer Parameters")
[1bf33c1]478            dialog.set_slicer(self.slicer.__class__.__name__,
479                            self.slicer.get_params())
480            if dialog.ShowModal() == wx.ID_OK:
481                dialog.Destroy() 
482       
[6c0568b]483       
[1bf33c1]484    def onSectorQ(self, event):
485        """
[6c0568b]486            Perform sector averaging on Q and draw sector slicer
[1bf33c1]487        """
[ef0c170]488        from SectorSlicer import SectorInteractor
[1bf33c1]489        self.onClearSlicer(event)
[d468daa]490        wx.PostEvent(self, InternalEvent(slicer= SectorInteractor))
[1bf33c1]491       
492    def onSectorPhi(self, event):
493        """
[6c0568b]494            Perform sector averaging on Phi and draw annulus slicer
[1bf33c1]495        """
[ef0c170]496        from AnnulusSlicer import AnnulusInteractor
[1bf33c1]497        self.onClearSlicer(event)
[d468daa]498        wx.PostEvent(self, InternalEvent(slicer= AnnulusInteractor))
[1bf33c1]499       
[7ab9241]500    def onBoxSum(self,event):
501        from boxSum import BoxSum
502        self.onClearSlicer(event)
[6c0568b]503                   
[54cc36a]504        self.slicer_z += 1
505        self.slicer =  BoxSum(self, self.subplot, zorder=self.slicer_z)
[6c0568b]506       
[54cc36a]507        self.subplot.set_ylim(self.data2D.ymin, self.data2D.ymax)
508        self.subplot.set_xlim(self.data2D.xmin, self.data2D.xmax)
509       
510        self.update()
511        self.slicer.update()
[6c0568b]512        ## Value used to initially set the slicer panel
513        type = self.slicer.__class__.__name__
514        params = self.slicer.get_params()
515        ## Create a new panel to display results of summation of Data2D
[8a7a21b]516        from slicerpanel import SlicerPanel
[6c0568b]517        new_panel = SlicerPanel(parent= self.parent, id= -1,
518                                    base= self, type= type,
519                                    params= params, style= wx.RAISED_BORDER)
520       
521        new_panel.window_caption=self.slicer.__class__.__name__+" "+ str(self.data2D.name)
522        new_panel.window_name = self.slicer.__class__.__name__+" "+ str(self.data2D.name)
523        ## Store a reference of the new created panel
[54cc36a]524        self.panel_slicer= new_panel
[6c0568b]525        ## save the window_caption of the new panel in the current slicer
[0bd2cd8]526        self.slicer.set_panel_name( name= new_panel.window_caption)
[6c0568b]527        ## post slicer panel to guiframe to display it
[54cc36a]528        from sans.guicomm.events import SlicerPanelEvent
[1debb29]529        wx.PostEvent(self.parent, SlicerPanelEvent (panel= self.panel_slicer,
530                                                    main_panel =self))
[6c0568b]531
[8a7a21b]532       
533    def onBoxavgX(self,event):
[6c0568b]534        """
535            Perform 2D data averaging on Qx
536            Create a new slicer .
537            @param event: wx.menu event
538        """
[8a7a21b]539        from boxSlicer import BoxInteractorX
[38224f10]540        self.onClearSlicer(event)
[d468daa]541        wx.PostEvent(self, InternalEvent(slicer= BoxInteractorX))
542       
543       
[8a7a21b]544    def onBoxavgY(self,event):
[6c0568b]545        """
546            Perform 2D data averaging on Qy
547            Create a new slicer .
548            @param event: wx.menu event
549        """
[8a7a21b]550        from boxSlicer import BoxInteractorY
551        self.onClearSlicer(event)
[d468daa]552        wx.PostEvent(self, InternalEvent(slicer= BoxInteractorY))
[6c0568b]553       
[b319def8]554       
[1bf33c1]555    def onClearSlicer(self, event):
556        """
557            Clear the slicer on the plot
558        """
559        if not self.slicer==None:
560            self.slicer.clear()
561            self.subplot.figure.canvas.draw()
562            self.slicer = None
563       
564            # Post slicer None event
565            event = self._getEmptySlicerEvent()
[d468daa]566            wx.PostEvent(self, event)
[3562fbc]567   
Note: See TracBrowser for help on using the repository browser.