source: sasview/sansguiframe/src/sans/guiframe/local_perspectives/plotting/masking.py @ cd2209d

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 cd2209d was 3858e0f, checked in by Jae Cho <jhjcho@…>, 13 years ago

minor fix in saving as data

  • Property mode set to 100644
File size: 21.2 KB
RevLine 
[c5874f2]1
[d955bf19]2################################################################################
3#This software was developed by the University of Tennessee as part of the
4#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
5#project funded by the US National Science Foundation.
6#
7#If you use DANSE applications to do scientific research that leads to
8#publication, we ask that you acknowledge the use of the software with the
9#following sentence:
10#
[21969a4a]11#This work benefited from DANSE software developed under NSF award DMR-0520547.
[d955bf19]12#
13#copyright 2008, University of Tennessee
14################################################################################
[c5874f2]15
16
[a5ca7ef]17##Todo: cleaning up, improving the maskplotpanel initialization, and testing.
[c5874f2]18import wx
19import sys
[32c0841]20import pylab
21import math
22import copy
23import numpy
[c5874f2]24from danse.common.plottools.PlotPanel import PlotPanel
[a5ca7ef]25from danse.common.plottools.plottables import Graph
[c5874f2]26from binder import BindArtist
27from sans.guiframe.dataFitting import Data2D
28from boxMask import BoxMask
29from sectorMask import SectorMask
[55a0dc1]30from sans.guiframe.events import SlicerEvent
31from sans.guiframe.events import StatusEvent
[32c0841]32(InternalEvent, EVT_INTERNAL) = wx.lib.newevent.NewEvent()
[c5874f2]33
[32c0841]34DEFAULT_CMAP = pylab.cm.jet
[c5874f2]35_BOX_WIDTH = 76
36_SCALE = 1e-6
[ca3b45e7]37_STATICBOX_WIDTH = 380
38PANEL_SIZE = 420
[c5874f2]39#SLD panel size
[32c0841]40if sys.platform.count("win32") > 0:
[c5874f2]41    FONT_VARIANT = 0
42else:
43    FONT_VARIANT = 1
44   
45
46class MaskPanel(wx.Dialog):
47    """
[d955bf19]48    Provides the Mask Editor GUI.
[c5874f2]49    """
50    ## Internal nickname for the window, used by the AUI manager
51    window_name = "Mask Editor"
52    ## Name to appear on the window title bar
53    window_caption = "Mask Editor"
54    ## Flag to tell the AUI manager to put this panel in the center pane
55    CENTER_PANE = True
[32c0841]56    def __init__(self, parent=None, base=None, 
57                 data=None, id=-1, *args, **kwds):
[c5874f2]58        kwds["style"] = wx.DEFAULT_DIALOG_STYLE
[32c0841]59        kwds["size"] = wx.Size(_STATICBOX_WIDTH * 2, PANEL_SIZE) 
60        wx.Dialog.__init__(self, parent, id=id,  *args, **kwds)
61       
[c5874f2]62        if data != None:
63            #Font size
[32c0841]64            kwds = []
[c5874f2]65            self.SetWindowVariant(variant=FONT_VARIANT)
[32c0841]66            self.SetTitle("Mask Editor for " + data.name)
[c5874f2]67            self.parent = base
68            self.data = data
69            self.str = self.data.__str__()
70            ## mask for 2D
71            self.mask = data.mask
72            self.default_mask = copy.deepcopy(data.mask)
73            ## masked data from GUI
74            self.slicer_mask = None
75            self.slicer = None
76            self.slicer_z = 5
77            self.data.interactive = True
78            ## when 2 data have the same id override the 1 st plotted
79            self.name = self.data.name
80            # Panel for 2D plot
[32c0841]81            self.plotpanel = Maskplotpanel(self, -1,
82                                           style=wx.TRANSPARENT_WINDOW)
[c5874f2]83            self.cmap = DEFAULT_CMAP
84            ## Create Artist and bind it
85            self.subplot = self.plotpanel.subplot
86            self.connect = BindArtist(self.subplot.figure)
87            self._setup_layout()
[32c0841]88            self.newplot = Data2D(image=self.data.data)
[c5874f2]89            self.newplot.setValues(self.data)
90            self.plotpanel.add_image(self.newplot) 
91            self._update_mask(self.mask)
92            self.Centre()
93            self.Layout()
94            # bind evt_close to _draw in fitpage
[8c21d53]95            self.Bind(wx.EVT_CLOSE, self.OnClose)
[c5874f2]96           
97    def ShowMessage(self, msg=''):
98        """
[d955bf19]99        Show error message when mask covers whole data area
[c5874f2]100        """
101        mssg = 'Erase, redraw or clear the mask. \n\r'
102        mssg += 'The data range can not be completely masked... \n\r'
103        mssg += msg
[32c0841]104        wx.MessageBox(mssg, 'Error', wx.OK | wx.ICON_ERROR)
[c5874f2]105   
106    def _setup_layout(self):
107        """
[d955bf19]108        Set up the layout
[c5874f2]109        """
110        shape = "Select a Shape for Masking:"
111        #  panel
[32c0841]112        sizer = wx.GridBagSizer(10, 10)
[c5874f2]113        #---------inputs----------------
114        shape_txt = wx.StaticText(self, -1, shape) 
[32c0841]115        sizer.Add(shape_txt, (1, 1), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=5)
116        self.innersector_rb = wx.RadioButton(self, -1, "Double Wings")
117        self.Bind(wx.EVT_RADIOBUTTON, self.onInnerSectorMask,
118                  id=self.innersector_rb.GetId())
119        sizer.Add(self.innersector_rb, (2, 1), 
120                  flag=wx.RIGHT|wx.BOTTOM, border=5)
121        self.innercircle_rb = wx.RadioButton(self, -1, "Circular Disk")
122        self.Bind(wx.EVT_RADIOBUTTON, self.onInnerRingMask,
123                  id=self.innercircle_rb.GetId())
124        sizer.Add(self.innercircle_rb, (3, 1),
125                   flag=wx.RIGHT|wx.BOTTOM, border=5)
126       
127        self.innerbox_rb = wx.RadioButton(self, -1, "Rectangular Disk")
128        self.Bind(wx.EVT_RADIOBUTTON, self.onInnerBoxMask,
129                  id=self.innerbox_rb.GetId())
130        sizer.Add(self.innerbox_rb, (4, 1), flag=wx.RIGHT|wx.BOTTOM, border=5)
[21969a4a]131
[32c0841]132        self.outersector_rb = wx.RadioButton(self, -1, "Double Wing Window")
133        self.Bind(wx.EVT_RADIOBUTTON, self.onOuterSectorMask, 
134                  id=self.outersector_rb.GetId())
135        sizer.Add(self.outersector_rb, (5, 1),
136                  flag=wx.RIGHT|wx.BOTTOM, border=5)
[c5874f2]137       
138        #outersector_y_txt = wx.StaticText(self, -1, 'Outer Sector')
[32c0841]139        self.outercircle_rb = wx.RadioButton(self, -1, "Circular Window")
140        self.Bind(wx.EVT_RADIOBUTTON, self.onOuterRingMask,
141                  id=self.outercircle_rb.GetId())
142        sizer.Add(self.outercircle_rb, (6, 1), 
143                  flag=wx.RIGHT|wx.BOTTOM, border=5)
[c5874f2]144        #outerbox_txt = wx.StaticText(self, -1, 'Outer Box')
[32c0841]145        self.outerbox_rb = wx.RadioButton(self, -1, "Rectangular Window")
146        self.Bind(wx.EVT_RADIOBUTTON, self.onOuterBoxMask, 
147                  id=self.outerbox_rb.GetId())
148        sizer.Add(self.outerbox_rb, (7, 1), flag=wx.RIGHT|wx.BOTTOM, border=5)
[c5874f2]149        self.innercircle_rb.SetValue(False)
150        self.outercircle_rb.SetValue(False)       
151        self.innerbox_rb.SetValue(False)
152        self.outerbox_rb.SetValue(False)
153        self.innersector_rb.SetValue(False)
154        self.outersector_rb.SetValue(False)
[32c0841]155        sizer.Add(self.plotpanel, (0, 2), (13, 13), 
156                  wx.EXPAND|wx.LEFT|wx.RIGHT, 15)
[c5874f2]157
158        #-----Buttons------------1
[21969a4a]159        id_button = wx.NewId()
160        button_add = wx.Button(self, id_button, "Add")
[c5874f2]161        button_add.SetToolTipString("Add the mask drawn.")
[32c0841]162        button_add.Bind(wx.EVT_BUTTON, self.onAddMask, id=button_add.GetId()) 
[c5874f2]163        sizer.Add(button_add, (13, 7))
[21969a4a]164        id_button = wx.NewId()
165        button_erase = wx.Button(self, id_button, "Erase")
[c5874f2]166        button_erase.SetToolTipString("Erase the mask drawn.")
[32c0841]167        button_erase.Bind(wx.EVT_BUTTON, self.onEraseMask,
168                          id=button_erase.GetId()) 
[c5874f2]169        sizer.Add(button_erase, (13, 8))
[21969a4a]170        id_button = wx.NewId()
171        button_reset = wx.Button(self, id_button, "Reset")
[c5874f2]172        button_reset.SetToolTipString("Reset the mask.")
[32c0841]173        button_reset.Bind(wx.EVT_BUTTON, self.onResetMask,
174                          id=button_reset.GetId()) 
175        sizer.Add(button_reset, (13, 9), flag=wx.RIGHT|wx.BOTTOM, border=15)
[21969a4a]176        id_button = wx.NewId()
177        button_reset = wx.Button(self, id_button, "Clear")
[c5874f2]178        button_reset.SetToolTipString("Clear all mask.")
[32c0841]179        button_reset.Bind(wx.EVT_BUTTON, self.onClearMask,
180                          id=button_reset.GetId()) 
181        sizer.Add(button_reset, (13, 10), flag=wx.RIGHT|wx.BOTTOM, border=15)
[c5874f2]182        sizer.AddGrowableCol(3)
183        sizer.AddGrowableRow(2)
184        self.SetSizerAndFit(sizer)
185        self.Centre()
186        self.Show(True)
187
[32c0841]188    def onInnerBoxMask(self, event=None):
[c5874f2]189        """
[d955bf19]190        Call Draw Box Slicer and get mask inside of the box
[c5874f2]191        """
192        #get ready for next evt
193        event.Skip()       
[32c0841]194        #from boxMask import BoxMask
195        if event != None:
196            self.onClearSlicer(event)         
[c5874f2]197        self.slicer_z += 1
[32c0841]198        self.slicer =  BoxMask(self, self.subplot,
199                               zorder=self.slicer_z, side=True)
[c5874f2]200        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
201        self.subplot.set_xlim(self.data.xmin, self.data.xmax)
202        self.update()
203        self.slicer_mask = self.slicer.update()
204       
[32c0841]205    def onOuterBoxMask(self, event=None):
[c5874f2]206        """
[d955bf19]207        Call Draw Box Slicer and get mask outside of the box
[c5874f2]208        """
209        event.Skip()       
[32c0841]210        #from boxMask import BoxMask
211        if event != None:
212            self.onClearSlicer(event)     
[c5874f2]213        self.slicer_z += 1
[32c0841]214        self.slicer =  BoxMask(self, self.subplot,
215                               zorder=self.slicer_z, side=False)
[c5874f2]216        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
217        self.subplot.set_xlim(self.data.xmin, self.data.xmax)
218        self.update()
219        self.slicer_mask = self.slicer.update()
220
[32c0841]221    def onInnerSectorMask(self, event=None):
[c5874f2]222        """
[d955bf19]223        Call Draw Sector Slicer and get mask inside of the sector
[c5874f2]224        """
225        event.Skip()
226        from sectorMask import SectorMask
[32c0841]227        if event != None:
[c5874f2]228            self.onClearSlicer(event)
229        self.slicer_z += 1
[32c0841]230        self.slicer =  SectorMask(self, self.subplot,
231                                  zorder=self.slicer_z, side=True)
[c5874f2]232        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
233        self.subplot.set_xlim(self.data.xmin, self.data.xmax)   
234        self.update()
235        self.slicer_mask = self.slicer.update() 
[a5ca7ef]236
[c5874f2]237    def onOuterSectorMask(self,event=None):
238        """
[d955bf19]239        Call Draw Sector Slicer and get mask outside of the sector
[c5874f2]240        """
241        event.Skip()
242        from sectorMask import SectorMask
[32c0841]243        if event != None:
[c5874f2]244            self.onClearSlicer(event)
245        self.slicer_z += 1
[32c0841]246        self.slicer =  SectorMask(self, self.subplot,
247                                  zorder=self.slicer_z, side=False)
[c5874f2]248        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
249        self.subplot.set_xlim(self.data.xmin, self.data.xmax)   
250        self.update()     
251        self.slicer_mask = self.slicer.update()   
[a5ca7ef]252
[c5874f2]253    def onInnerRingMask(self, event=None):
254        """
[d955bf19]255        Perform inner circular cut on Phi and draw circular slicer
[c5874f2]256        """
257        event.Skip()
258        from AnnulusSlicer import CircularMask
[32c0841]259        if event != None:
[c5874f2]260            self.onClearSlicer(event)
261        self.slicer_z += 1
[21969a4a]262        self.slicer = CircularMask(self, self.subplot,
[32c0841]263                                   zorder=self.slicer_z, side=True)
[c5874f2]264        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
265        self.subplot.set_xlim(self.data.xmin, self.data.xmax)   
266        self.update()
267        self.slicer_mask = self.slicer.update() 
[a5ca7ef]268
[c5874f2]269    def onOuterRingMask(self, event=None):
270        """
[d955bf19]271        Perform outer circular cut on Phi and draw circular slicer
[c5874f2]272        """
273        event.Skip()
274        from AnnulusSlicer import CircularMask
[32c0841]275        if event != None:
[c5874f2]276            self.onClearSlicer(event)
277        self.slicer_z += 1
[32c0841]278        self.slicer = CircularMask(self,self.subplot,
279                                   zorder=self.slicer_z, side=False)   
[c5874f2]280        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
281        self.subplot.set_xlim(self.data.xmin, self.data.xmax)
282        self.update()
283        self.slicer_mask = self.slicer.update()     
284       
285    def onAddMask(self, event):
286        """
[d955bf19]287        Add new mask to old mask
[c5874f2]288        """
[32c0841]289        if not self.slicer == None:
[c5874f2]290            data = Data2D()
291            data = self.data
292            self.slicer_mask = self.slicer.update()
293            data.mask = self.data.mask & self.slicer_mask
294            self._check_display_mask(data.mask, event)
295           
296    def _check_display_mask(self, mask, event):
297        """
[d955bf19]298        check if the mask valid and update the plot
299       
300        :param mask: mask data
[c5874f2]301        """
302        ## Redraw the current image
303        self._update_mask(mask)
304
305    def onEraseMask(self, event):
306        """
[d955bf19]307        Erase new mask from old mask
[c5874f2]308        """
309        if not self.slicer==None:
310            self.slicer_mask = self.slicer.update()
311            mask = self.data.mask
312            mask[self.slicer_mask==False] = True
313            self._check_display_mask(mask, event)
314           
315    def onResetMask(self, event):
316        """
[d955bf19]317        Reset mask to the original mask
318        """       
[c5874f2]319        self.slicer_z += 1
[32c0841]320        self.slicer =  BoxMask(self, self.subplot, 
321                               zorder=self.slicer_z, side=True)
[c5874f2]322        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
323        self.subplot.set_xlim(self.data.xmin, self.data.xmax)   
324        mask = copy.deepcopy(self.default_mask)
325        self.data.mask = mask
326        # update mask plot
327        self._check_display_mask(mask, event)
328       
329    def onClearMask(self, event):
330        """
[d955bf19]331        Clear mask
[c5874f2]332        """           
333        self.slicer_z += 1
[32c0841]334        self.slicer =  BoxMask(self, self.subplot,
335                               zorder=self.slicer_z, side=True)
[c5874f2]336        self.subplot.set_ylim(self.data.ymin, self.data.ymax)
337        self.subplot.set_xlim(self.data.xmin, self.data.xmax)   
338        #mask = copy.deepcopy(self.default_mask)
339        mask = numpy.ones(len(self.data.mask), dtype=bool)
340        self.data.mask = mask
341        # update mask plot
342        self._check_display_mask(mask, event)
343       
344    def onClearSlicer(self, event):
345        """
[d955bf19]346        Clear the slicer on the plot
[c5874f2]347        """
[32c0841]348        if not self.slicer == None:
[c5874f2]349            self.slicer.clear()
350            self.subplot.figure.canvas.draw()
351            self.slicer = None
352
353    def _setSlicer(self):
354        """
[d955bf19]355        Clear the previous slicer and create a new one.Post an internal
356        event.
357       
358        :param slicer: slicer class to create
359        """
[c5874f2]360        ## Clear current slicer
361        if not self.slicer == None: 
362            self.slicer.clear()           
363        ## Create a new slicer   
364        self.slicer_z += 1
365        self.slicer = slicer(self, self.subplot, zorder=self.slicer_z)
366        self.subplot.set_ylim(self.data2D.ymin, self.data2D.ymax)
367        self.subplot.set_xlim(self.data2D.xmin, self.data2D.xmax)
368        ## Draw slicer
369        self.update()
370        self.slicer.update()
[32c0841]371        msg = "Plotter2D._setSlicer  %s"%self.slicer.__class__.__name__
372        wx.PostEvent(self.parent, StatusEvent(status=msg))
[c5874f2]373        # Post slicer event
374        event = self._getEmptySlicerEvent()
375        event.type = self.slicer.__class__.__name__
376        event.obj_class = self.slicer.__class__
377        event.params = self.slicer.get_params()
378        wx.PostEvent(self, event)
379   
380    def update(self, draw=True):
381        """
[d955bf19]382        Respond to changes in the model by recalculating the
383        profiles and resetting the widgets.
[c5874f2]384        """
385        self.plotpanel.draw()
386       
387    def _set_mask(self, mask):
388        """
[d955bf19]389        Set mask
[c5874f2]390        """
391        self.data.mask = mask
392       
[3858e0f]393    def set_plot_unfocus(self):
394        """
395        Not implemented
396        """
397        pass
398   
[c5874f2]399    def _update_mask(self,mask):
400        """
[d955bf19]401        Respond to changes in masking
[c5874f2]402        """ 
403        # the case of liitle numbers of True points
[32c0841]404        if (len(mask[mask]) < 10 and self.data != None):
[c5874f2]405            self.ShowMessage()
406            mask = copy.deepcopy(self.mask)
407            self.data.mask = mask
408        else:
409            self.mask = mask
410        # make temperary data to plot
411        temp_mask = numpy.zeros(len(mask))
412        temp_data = copy.deepcopy(self.data)
413        # temp_data default is None
414        # This method is to distinguish between masked point and data point = 0.
415        temp_mask = temp_mask/temp_mask
416        temp_mask[mask] = temp_data.data[mask]
417        # set temp_data value for self.mask==True, else still None
418        #temp_mask[mask] = temp_data[mask]
419        temp_data.data[mask==False] = temp_mask[mask==False]
420        self.plotpanel.clear()
421        if self.slicer != None:
422            self.slicer.clear()
423            self.slicer = None
424        # Post slicer None event
425        event = self._getEmptySlicerEvent()
426        wx.PostEvent(self, event)
[9266c66]427       
[ca6c17e8]428        ##use this method
[e306b96e]429        #set zmax and zmin to plot: Fix it w/ data.
430        if self.plotpanel.scale == 'log':
431            zmax = math.log(max(self.data.data[self.data.data>0]))
[c1d2af4]432            zmin = math.log(min(self.data.data[self.data.data>0]))
[e306b96e]433        else:
434            zmax = max(self.data.data[self.data.data>0])
435            zmin = min(self.data.data[self.data.data>0])
[ca6c17e8]436        #plot   
[32c0841]437        plot = self.plotpanel.image(data=temp_mask,
[c5874f2]438                       qx_data=self.data.qx_data,
439                       qy_data=self.data.qy_data,
[32c0841]440                       xmin=self.data.xmin,
441                       xmax=self.data.xmax,
442                       ymin=self.data.ymin,
443                       ymax=self.data.ymax,
444                       zmin=zmin,
445                       zmax=zmax,
446                       cmap=self.cmap,
447                       color=0, symbol=0, label=self.data.name)
[54180f9]448        # axis labels
[0aee80d]449        self.plotpanel.axes[0].set_xlabel('$\\rm{Q}_{x}(A^{-1})$')
450        self.plotpanel.axes[0].set_ylabel('$\\rm{Q}_{y}(A^{-1})$')
[c5874f2]451        self.plotpanel.render()
452        self.plotpanel.subplot.figure.canvas.draw_idle()
453       
454    def _getEmptySlicerEvent(self):
455        """
[d955bf19]456        create an empty slicervent
[c5874f2]457        """
458        self.innerbox_rb.SetValue(False)
459        self.outerbox_rb.SetValue(False)
460        self.innersector_rb.SetValue(False)
461        self.outersector_rb.SetValue(False)
462        self.innercircle_rb.SetValue(False)
463        self.outercircle_rb.SetValue(False)
464        return SlicerEvent(type=None,
465                           params=None,
466                           obj_class=None) 
467             
[32c0841]468    def _draw_model(self, event):
[c5874f2]469        """
[d955bf19]470         on_close, update the model2d plot
[c5874f2]471        """
472        pass
473       
474    def freeze_axes(self):
[d955bf19]475        """
[21969a4a]476        freeze axes
[d955bf19]477        """
[c5874f2]478        self.plotpanel.axes_frozen = True
[d955bf19]479       
[c5874f2]480    def thaw_axes(self):
[d955bf19]481        """
[21969a4a]482        thaw axes
[d955bf19]483        """
484        self.plotpanel.axes_frozen = False       
485         
[32c0841]486    def onMouseMotion(self, event):
[d955bf19]487        """
[21969a4a]488        onMotion event
[d955bf19]489        """
[c5874f2]490        pass
[d955bf19]491   
[c5874f2]492    def onWheel(self, event):
[d955bf19]493        """
[21969a4a]494        on wheel event
[d955bf19]495        """
[c5874f2]496        pass 
[309a1f0]497   
498    def OnClose(self, event):
499        """
500        """
[c365765]501        self.parent._draw_masked_model(event)
[25952cd]502       
[a5ca7ef]503class Maskplotpanel(PlotPanel):
[d955bf19]504    """
505    """
[32c0841]506    def __init__(self, parent, id=-1, color=None, dpi=None, **kwargs):
[d955bf19]507        """
508        """
[c5874f2]509        PlotPanel.__init__(self, parent, id=id, color=color, dpi=dpi, **kwargs)
510       
511        # Keep track of the parent Frame
512        self.parent = parent
513        # Internal list of plottable names (because graph
514        # doesn't have a dictionary of handles for the plottables)
515        self.plots = {}
[a5ca7ef]516        self.graph = Graph()
[c5874f2]517       
518    def add_toolbar(self):
519        """
[d955bf19]520        Add toolbar
[c5874f2]521        """
522        # Not implemented
523        pass
524    def on_set_focus(self, event):
525        """
[d955bf19]526        send to the parenet the current panel on focus
[c5874f2]527        """
528        #change the panel background
529        #self.SetColor((170, 202, 255))
530        self.draw()   
531         
532    def add_image(self, plot):
[d955bf19]533        """
[21969a4a]534        Add Image
[d955bf19]535        """
[c5874f2]536        self.plots[plot.name] = plot
[a5ca7ef]537        #init graph
538        self.gaph = Graph()
539        #add plot
[c5874f2]540        self.graph.add(plot)
[a5ca7ef]541        #add axes
[c5874f2]542        self.graph.xaxis('\\rm{Q}_{x} ', 'A^{-1}')
543        self.graph.yaxis('\\rm{Q}_{y} ', 'A^{-1}')
[a5ca7ef]544        #draw
[c5874f2]545        self.graph.render(self)
546        self.subplot.figure.canvas.draw_idle()
[a5ca7ef]547       
[c5874f2]548    def onMouseMotion(self, event):
549        """
[d955bf19]550        Disable dragging 2D image
[c5874f2]551        """
552        pass
553   
554    def onContextMenu(self, event):
555        """
[d955bf19]556        Default context menu for a plot panel
[c5874f2]557        """
558        # Slicer plot popup menu
[b40439d9]559        slicerpop = wx.Menu()
[c5874f2]560       
[21969a4a]561        id_cm = wx.NewId()
562        slicerpop.Append(id_cm, '&Toggle Linear/Log scale')
563        wx.EVT_MENU(self, id_cm, self._onToggleScale)
[c5874f2]564               
565        pos = event.GetPosition()
566        pos = self.ScreenToClient(pos)
567        self.PopupMenu(slicerpop, pos)
568
[e306b96e]569class ViewerFrame(wx.Frame):
[b9d68ff]570    """
571    Add comment
572    """
[e306b96e]573    def __init__(self, parent, id, title):
[b9d68ff]574        """
575        comment
576        :param parent: parent panel/container
577        """
[e306b96e]578        # Initialize the Frame object
[32c0841]579        wx.Frame.__init__(self, parent, id, title,
580                          wx.DefaultPosition, wx.Size(950, 850))
[e306b96e]581        # Panel for 1D plot
[32c0841]582        self.plotpanel = Maskplotpanel(self, -1, style=wx.RAISED_BORDER)
[c5874f2]583
[e306b96e]584class ViewApp(wx.App):
585    def OnInit(self):
586        frame = ViewerFrame(None, -1, 'testView')   
587        frame.Show(True)
[fdc127c]588        #self.SetTopWindow(frame)
[e306b96e]589       
590        return True
591               
[c5874f2]592if __name__ == "__main__": 
593    app = ViewApp(0)
594    app.MainLoop()     
Note: See TracBrowser for help on using the repository browser.