source: sasview/src/sans/guiframe/local_perspectives/plotting/Plotter1D.py @ b9f6d83

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 b9f6d83 was b9f6d83, checked in by Mathieu Doucet <doucetm@…>, 10 years ago

Re #216 Merging wx30 branch

  • Property mode set to 100644
File size: 33.4 KB
Line 
1
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#See the license text in license.txt
8#
9#copyright 2008, University of Tennessee
10################################################################################
11
12
13import wx
14import sys
15import math
16import numpy
17
18from sans.plottools.PlotPanel import PlotPanel
19from sans.guiframe.events import StatusEvent
20from sans.guiframe.events import PanelOnFocusEvent
21from sans.guiframe.utils import PanelMenu
22from sans.guiframe.panel_base import PanelBase
23from sans.guiframe.gui_style import GUIFRAME_ICON
24from appearanceDialog import appearanceDialog
25from graphAppearance import graphAppearance
26
27DEFAULT_QMAX = 0.05
28DEFAULT_QSTEP = 0.001
29DEFAULT_BEAM = 0.005
30BIN_WIDTH = 1
31IS_MAC = (sys.platform == 'darwin')
32
33
34def find_key(dic, val):
35    """return the key of dictionary dic given the value"""
36    return [k for k, v in dic.iteritems() if v == val][0]
37
38
39
40class ModelPanel1D(PlotPanel, PanelBase):
41    """
42    Plot panel for use with the GUI manager
43    """
44   
45    ## Internal name for the AUI manager
46    window_name = "plotpanel"
47    ## Title to appear on top of the window
48    window_caption = "Graph"
49    ## Flag to tell the GUI manager that this panel is not
50    #  tied to any perspective
51    ALWAYS_ON = True
52    ## Group ID
53    group_id = None
54   
55    def __init__(self, parent, id=-1, color = None,
56                 dpi=None, style=wx.NO_FULL_REPAINT_ON_RESIZE, **kwargs):
57        PlotPanel.__init__(self, parent, id=id, style=style, **kwargs)
58        PanelBase.__init__(self, parent)
59        ## Reference to the parent window
60        self.parent = parent
61        if hasattr(parent, "parent"):
62            self.parent = self.parent.parent
63        ## Plottables
64        self.plots = {}
65        self.frame = None
66        #context menu
67        self._slicerpop = None
68       
69        self._available_data = []
70        self._menu_add_ids = []
71        self._symbol_labels = self.get_symbol_label()
72        self._color_labels = self.get_color_label()
73        self.currColorIndex = ""
74        self._is_changed_legend_label = False
75        self.is_xtick = False
76        self.is_ytick = False
77     
78        self.hide_menu = None
79        ## Unique ID (from gui_manager)
80        self.uid = None
81        self.x_size = None
82        ## Default locations
83        #self._default_save_location = os.getcwd()
84        self.size = None 
85        self.vl_ind = 0     
86        ## Graph       
87        #self.graph = Graph()
88        self.graph.xaxis("\\rm{Q}", 'A^{-1}')
89        self.graph.yaxis("\\rm{Intensity} ", "cm^{-1}")
90        self.graph.render(self)
91        self.cursor_id = None
92       
93        # In resizing event
94        self.resizing = False
95        self.canvas.set_resizing(self.resizing)
96        self.Bind(wx.EVT_SIZE, self._OnReSize)
97        self._add_more_tool()
98        self.parent.SetFocus()
99       
100       
101    def get_symbol_label(self):
102        """
103        Associates label to symbol
104        """
105        _labels = {}
106        i = 0
107        _labels['Circle'] = i
108        i += 1
109        _labels['Cross X '] = i
110        i += 1
111        _labels['Triangle Down'] = i
112        i += 1
113        _labels['Triangle Up'] = i
114        i += 1
115        _labels['Triangle Left'] = i
116        i += 1
117        _labels['Triangle Right'] = i
118        i += 1
119        _labels['Cross +'] = i
120        i += 1
121        _labels['Square'] = i
122        i += 1
123        _labels['diamond'] = i
124        i += 1
125        _labels['Diamond'] = i
126        i += 1
127        _labels['Hexagon1'] = i
128        i += 1
129        _labels['Hexagon2'] = i
130        i += 1
131        _labels['Pentagon'] = i
132        i += 1
133        _labels['Line'] = i
134        i += 1
135        _labels['Dash'] = i
136        i += 1
137        _labels['Vline'] = i
138        i += 1
139        _labels['Step'] = i
140        return _labels
141   
142    def get_color_label(self):
143        """
144        Associates label to a specific color
145        """
146        _labels = {}
147        i = 0
148        _labels['Blue'] = i
149        i += 1
150        _labels['Green'] = i
151        i += 1
152        _labels['Red'] = i
153        i += 1
154        _labels['Cyan'] = i
155        i += 1
156        _labels['Magenta'] = i
157        i += 1
158        _labels['Yellow'] = i
159        i += 1
160        _labels['Black'] = i
161        return _labels
162
163   
164    def set_data(self, list=None):
165        """
166        """
167        pass
168   
169    def _reset(self):
170        """
171        Resets internal data and graph
172        """   
173        self.graph.reset()
174        self.plots      = {}
175        if self.is_zoomed:
176            self.is_zoomed = False
177       
178    def _OnReSize(self, event):   
179        """
180        On response of the resize of a panel, set axes_visiable False
181        """
182        # It was found that wx >= 2.9.3 sends an event even if no size changed.
183        # So manually recode the size (=x_size) and compare here.
184        # Massy code to work around:<
185        if self.parent._mgr != None:
186            max_panel = self.parent._mgr.GetPane(self)
187            if max_panel.IsMaximized():
188                self.parent._mgr.RestorePane(max_panel)
189                max_panel.Maximize()
190        if self.x_size != None:
191            if self.x_size == self.GetSize():
192                self.resizing = False
193                self.canvas.set_resizing(self.resizing)
194                return
195        self.x_size = self.GetSize()
196
197        # Ready for another event
198        # Do not remove this Skip. Otherwise it will get runtime error on wx>=2.9.
199        event.Skip() 
200        # set the resizing flag
201        self.resizing = True
202        self.canvas.set_resizing(self.resizing)
203        self.parent.set_schedule(True)
204        pos_x, pos_y = self.GetPositionTuple()
205        if pos_x != 0 and pos_y != 0:
206            self.size, _ = self.GetClientSizeTuple()
207        self.SetSizer(self.sizer)
208        wx.CallAfter(self.parent.disable_app_menu,self)
209       
210    def on_plot_qrange(self, event=None):
211        """
212        On Qmin Qmax vertical line event
213        """
214        if event == None:
215            return
216        event.Skip() 
217        active_ctrl = event.active
218        if active_ctrl == None:
219            return
220        if event.id in self.plots.keys():
221            # Set line position and color
222            colors = ['red', 'purple']
223            self.cursor_id = event.id
224            ctrl = event.ctrl
225            if self.ly == None:
226                self.ly = []
227                for ind_ly in range(len(colors)):
228                    self.ly.append(self.subplot.axvline(color=colors[ind_ly], 
229                                                        lw=2.5, alpha=0.7))
230                    self.ly[ind_ly].set_rasterized(True)     
231            try:
232                # Display x,y in the status bar if possible
233                xval = float(active_ctrl.GetValue())
234                position = self.get_data_xy_vals(xval)
235                if position != None:
236                    wx.PostEvent(self.parent, StatusEvent(status=position))
237            except:
238                pass
239            if not event.leftdown:
240                # text event
241                try:
242                    is_moved = False
243                    for idx in range(len(self.ly)):
244                        val = float(ctrl[idx].GetValue())
245                        # check if vline moved
246                        if self.ly[idx].get_xdata() != val:
247                            self.ly[idx].set_xdata(val)
248                            is_moved = True
249                    if is_moved:
250                        self.canvas.draw() 
251                except:
252                    pass
253                event.Skip() 
254                return
255            self.q_ctrl = ctrl
256            try:
257                pos_x_min = float(self.q_ctrl[0].GetValue())
258            except:
259                pos_x_min = xmin
260            try:
261                pos_x_max = float(self.q_ctrl[1].GetValue())
262            except:
263                pos_x_max = xmax
264            pos_x = [pos_x_min, pos_x_max]
265            for ind_ly in range(len(colors)):
266                self.ly[ind_ly].set_color(colors[ind_ly])
267                self.ly[ind_ly].set_xdata(pos_x[ind_ly])
268            self.canvas.draw()
269        else:
270            self.q_ctrl = None
271   
272    def get_data_xy_vals(self, xval):
273        """
274        Get x, y data values near x = x_val
275        """
276        try:
277            x_data = self.plots[self.cursor_id].x
278            y_data = self.plots[self.cursor_id].y
279            indx = self._find_nearest(x_data, xval)
280            pos_x = x_data[indx]
281            pos_y = y_data[indx]
282            position = str(pos_x), str(pos_y)
283            return position
284        except:
285            return None
286           
287    def _find_nearest(self, array, value):
288        """
289        Find and return the nearest value in array to the value.
290        Used in cusor_line()
291        :Param array: numpy array
292        :Param value: float
293        """
294        idx = (numpy.abs(array - value)).argmin()
295        return int(idx)#array.flat[idx]
296   
297    def _check_line_positions(self, pos_x=None, nop=None):
298        """
299        Check vertical line positions
300        :Param pos_x: position of the current line [float]
301        :Param nop: number of plots [int]
302        """
303        ly = self.ly
304        ly0x = ly[0].get_xdata()
305        ly1x = ly[1].get_xdata()
306        self.q_ctrl[0].SetBackgroundColour('white')
307        self.q_ctrl[1].SetBackgroundColour('white')
308        if ly0x >= ly1x:
309            if self.vl_ind == 0:
310                ly[1].set_xdata(pos_x)
311                ly[1].set_zorder(nop)
312                self.q_ctrl[1].SetValue(str(pos_x))
313                self.q_ctrl[0].SetBackgroundColour('pink')
314            elif self.vl_ind == 1:
315                ly[0].set_xdata(pos_x)
316                ly[0].set_zorder(nop)
317                self.q_ctrl[0].SetValue(str(pos_x))
318                self.q_ctrl[1].SetBackgroundColour('pink')
319               
320    def _get_cusor_lines(self, event):
321        """
322        Revmove or switch cursor line if drawn
323        :Param event: LeftClick mouse event
324        """ 
325        ax = event.inaxes
326        if hasattr(event, "action"):
327            dclick = event.action == 'dclick'
328            if ax == None or dclick:
329                # remove the vline
330                self._check_zoom_plot()
331                self.canvas.draw()
332                self.q_ctrl = None
333                return 
334        if self.ly != None and event.xdata != None:
335            # Selecting a new line if cursor lines are displayed already
336            dqmin = math.fabs(event.xdata - self.ly[0].get_xdata())
337            dqmax = math.fabs(event.xdata - self.ly[1].get_xdata())
338            is_qmax = dqmin > dqmax
339            if is_qmax:
340                self.vl_ind = 1
341            else:
342                self.vl_ind = 0 
343                     
344    def cusor_line(self, event):
345        """
346        Move the cursor line to write Q range
347        """
348        if self.q_ctrl == None:
349            return
350        #release a q range vline
351        if self.ly != None and not self.leftdown:
352            for ly in self.ly:
353                ly.set_alpha(0.7)
354                self.canvas.draw()
355            return
356        ax = event.inaxes
357        if ax == None or not hasattr(event, 'action'):
358            return
359        end_drag = event.action != 'drag' and event.xdata != None
360        nop = len(self.plots)
361        pos_x, pos_y = float(event.xdata), float(event.ydata)
362        try:
363            ly = self.ly
364            ly0x = ly[0].get_xdata()
365            ly1x = ly[1].get_xdata()
366            if ly0x == ly1x:
367                if ly[0].get_zorder() > ly[1].get_zorder():
368                    self.vl_ind = 0
369                else:
370                    self.vl_ind = 1
371            vl_ind = self.vl_ind
372            x_data = self.plots[self.cursor_id].x
373            y_data = self.plots[self.cursor_id].y
374            xmin = x_data.min()
375            xmax = x_data.max()
376            indx = self._find_nearest(x_data, pos_x)
377            #pos_x = self._find_nearest(x_data, pos_x)
378            #indx = int(numpy.searchsorted(x_data, [pos_x])[0])
379            # Need to hold LeftButton to drag
380            if end_drag:
381                if event.button:
382                    self._check_line_positions(pos_x, nop)
383                return   
384            if indx >= len(x_data):
385                indx = len(x_data) - 1
386            pos_x = x_data[indx]
387            pos_y = y_data[indx]
388            if xmin == ly1x:
389                vl_ind = 1
390            elif xmax == ly0x:
391                vl_ind = 0
392            else:
393                ly[vl_ind].set_xdata(pos_x)
394                ly[vl_ind].set_zorder(nop + 1)
395                self._check_line_positions(pos_x, nop)
396            ly[vl_ind].set_xdata(pos_x)
397            ly[vl_ind].set_alpha(1.0)
398            ly[vl_ind].set_zorder(nop + 1)
399            self.canvas.draw()
400            self.q_ctrl[vl_ind].SetValue(str(pos_x))
401        except:
402            pass
403               
404    def set_resizing(self, resizing=False):
405        """
406        Set the resizing (True/False)
407        """
408        self.resizing = resizing
409        #self.canvas.set_resizing(resizing)
410   
411    def schedule_full_draw(self, func='append'):   
412        """
413        Put self in schedule to full redraw list
414        """
415        # append/del this panel in the schedule list
416        self.parent.set_schedule_full_draw(self, func)
417       
418
419    def remove_data_by_id(self, id):
420        """'
421        remove data from plot
422        """
423        if id in self.plots.keys():
424            data =  self.plots[id]
425            self.graph.delete(data)
426            data_manager = self._manager.parent.get_data_manager()
427            data_list, theory_list = data_manager.get_by_id(id_list=[id])
428           
429            if id in data_list.keys():
430                data = data_list[id]
431            if id in theory_list.keys():
432                data = theory_list[id]
433            # Update Graph menu and help string       
434            #h_id = self.parent._window_menu.FindItem(self.window_caption)
435            if data != None:
436                if data.__class__.__name__ == 'list':
437                    label = data[0].label
438                else:
439                    label = data.label
440            else:
441                label = '???'
442            #helpString = self.parent._window_menu.GetHelpString(h_id)
443            d_string = (' ' + str(label) +';')
444            #new_tip = helpString.replace(d_string, '')
445            #self.parent._window_menu.SetHelpString(h_id, new_tip) 
446
447            del self.plots[id]
448            self.graph.render(self)
449            self.subplot.figure.canvas.draw_idle()   
450            if len(self.graph.plottables) == 0:
451                #onRemove: graph is empty must be the panel must be destroyed
452                self.parent.delete_panel(self.uid)
453           
454       
455    def plot_data(self, data):
456        """
457        Data is ready to be displayed
458       
459        :param event: data event
460        """
461        if data.__class__.__name__ == 'Data2D':
462            return
463        plot_keys = self.plots.keys()
464        if data.id in plot_keys:
465            #Recover panel prop.s
466            xlo, xhi = self.subplot.get_xlim()
467            ylo, yhi = self.subplot.get_ylim()
468            old_data = self.plots[data.id]
469            if self._is_changed_legend_label:
470                data.label = old_data.label
471            if old_data.__class__.__name__ == 'Data1D':
472                data.custom_color = old_data.custom_color
473                data.symbol = old_data.symbol
474                data.markersize = old_data.markersize
475                data.zorder = len(plot_keys)
476            # Replace data
477            self.graph.replace(data)
478            self.plots[data.id] = data
479            ## Set the view scale for all plots
480            try:
481                self._onEVT_FUNC_PROPERTY()
482            except:
483                msg=" Encountered singular points..."
484                wx.PostEvent(self.parent, StatusEvent(status=\
485                    "Plotting Error: %s"% msg, info="error")) 
486            # Check if zoomed
487            try: tb = self.toolbar.wx_ids['Back']
488            except AttributeError: tb = self.toolbar._NTB2_BACK # Cruft
489            toolbar_zoomed = self.toolbar.GetToolEnabled(tb)
490            if self.is_zoomed or toolbar_zoomed:
491                # Recover the x,y limits
492                self.subplot.set_xlim((xlo, xhi))     
493                self.subplot.set_ylim((ylo, yhi)) 
494        else:
495            self.plots[data.id] = data
496            self.graph.add(self.plots[data.id]) 
497            data.zorder = len(plot_keys)
498            ## Set the view scale for all plots
499            try:
500                self._onEVT_FUNC_PROPERTY()
501                if IS_MAC:
502                    # MAC: forcing to plot 2D avg
503                    self.canvas._onDrawIdle()
504            except:
505                msg=" Encountered singular points..."
506                wx.PostEvent(self.parent, StatusEvent(status=\
507                    "Plotting Error: %s"% msg, info="error")) 
508            self.toolbar.update()
509            if self.is_zoomed:
510                self.is_zoomed = False
511            # Update Graph menu and help string       
512            #pos = self.parent._window_menu.FindItem(self.window_caption)
513            helpString = 'Show/Hide Graph: '
514            for plot in  self.plots.itervalues():
515                helpString += (' ' + str(plot.label) +';')
516            #self.parent._window_menu.SetHelpString(pos, helpString) 
517               
518    def draw_plot(self):
519        """
520        Draw plot
521        """
522        self.draw() 
523
524    def onLeftDown(self,event): 
525        """
526        left button down and ready to drag
527        Display the position of the mouse on the statusbar
528        """
529        #self.parent.set_plot_unfocus()
530        self._get_cusor_lines(event)
531        ax = event.inaxes
532        PlotPanel.onLeftDown(self, event)
533        if ax != None:
534            try:
535                pos_x = float(event.xdata)# / size_x
536                pos_y = float(event.ydata)# / size_y
537                pos_x = "%8.3g"% pos_x
538                pos_y = "%8.3g"% pos_y
539                self.position = str(pos_x), str(pos_y)
540                wx.PostEvent(self.parent, StatusEvent(status=self.position))
541            except:
542                self.position = None 
543        # unfocus all
544        self.parent.set_plot_unfocus() 
545        #post nd event to notify guiframe that this panel is on focus
546        wx.PostEvent(self.parent, PanelOnFocusEvent(panel=self))
547
548       
549    def _ontoggle_hide_error(self, event):
550        """
551        Toggle error display to hide or show
552        """
553        menu = event.GetEventObject()
554        id = event.GetId()
555        self.set_selected_from_menu(menu, id)
556        # Check zoom
557        xlo, xhi = self.subplot.get_xlim()
558        ylo, yhi = self.subplot.get_ylim()
559
560        selected_plot = self.plots[self.graph.selected_plottable]
561        if self.hide_menu.GetText() == "Hide Error Bar":
562            selected_plot.hide_error = True
563        else:
564            selected_plot.hide_error = False
565        ## increment graph color
566        self.graph.render(self)
567        self.subplot.figure.canvas.draw_idle() 
568        # Check if zoomed
569        try: tb = self.toolbar.wx_ids['Back']
570        except AttributeError: tb = self.toolbar._NTB2_BACK # Cruft
571        toolbar_zoomed = self.toolbar.GetToolEnabled(tb)
572        if self.is_zoomed or toolbar_zoomed:
573            # Recover the x,y limits
574            self.subplot.set_xlim((xlo, xhi))     
575            self.subplot.set_ylim((ylo, yhi)) 
576
577         
578    def _onRemove(self, event):
579        """
580        Remove a plottable from the graph and render the graph
581       
582        :param event: Menu event
583       
584        """
585        menu = event.GetEventObject()
586        id = event.GetId()
587        self.set_selected_from_menu(menu, id)
588        ## Check if there is a selected graph to remove
589        if self.graph.selected_plottable in self.plots.keys():
590            selected_plot = self.plots[self.graph.selected_plottable]
591            id = self.graph.selected_plottable
592            self.remove_data_by_id(id)
593           
594    def onContextMenu(self, event):
595        """
596        1D plot context menu
597       
598        :param event: wx context event
599       
600        """
601        self._slicerpop = PanelMenu()
602        self._slicerpop.set_plots(self.plots)
603        self._slicerpop.set_graph(self.graph)   
604        if not self.graph.selected_plottable in self.plots: 
605            # Various plot options
606            id = wx.NewId()
607            self._slicerpop.Append(id, '&Save Image', 'Save image as PNG')
608            wx.EVT_MENU(self, id, self.onSaveImage)
609            id = wx.NewId()
610            self._slicerpop.Append(id, '&Print Image', 'Print image ')
611            wx.EVT_MENU(self, id, self.onPrint)
612            id = wx.NewId()
613            self._slicerpop.Append(id, '&Print Preview', 'Print preview')
614            wx.EVT_MENU(self, id, self.onPrinterPreview)
615           
616            id = wx.NewId()
617            self._slicerpop.Append(id, '&Copy to Clipboard', 
618                                   'Copy to the clipboard')
619            wx.EVT_MENU(self, id, self.OnCopyFigureMenu)
620                   
621            self._slicerpop.AppendSeparator()
622
623        for plot in self.plots.values():
624            #title = plot.title
625            name = plot.name
626            plot_menu = wx.Menu()
627            if self.graph.selected_plottable:
628                if not self.graph.selected_plottable in self.plots.keys():
629                    continue
630                if plot != self.plots[self.graph.selected_plottable]:
631                    continue
632               
633            id = wx.NewId()
634            plot_menu.Append(id, "&DataInfo", name)
635            wx.EVT_MENU(self, id, self. _onDataShow)
636            id = wx.NewId()
637            plot_menu.Append(id, "&Save Points as a File", name)
638            wx.EVT_MENU(self, id, self._onSave)
639            plot_menu.AppendSeparator()
640           
641            #add menu of other plugins
642            item_list = self.parent.get_current_context_menu(self)
643             
644            if (not item_list == None) and (not len(item_list) == 0):
645                for item in item_list:
646
647                    try:
648                        id = wx.NewId()
649                        plot_menu.Append(id, item[0], name)
650                        wx.EVT_MENU(self, id, item[2])
651                    except:
652                        msg = "ModelPanel1D.onContextMenu: "
653                        msg += "bad menu item  %s" % sys.exc_value
654                        wx.PostEvent(self.parent, StatusEvent(status=msg))
655                        pass
656                plot_menu.AppendSeparator()
657           
658            if self.parent.ClassName.count('wxDialog') == 0: 
659                id = wx.NewId()
660                plot_menu.Append(id, '&Linear Fit', name)
661                wx.EVT_MENU(self, id, self.onFitting)
662                plot_menu.AppendSeparator()
663   
664                id = wx.NewId()
665                plot_menu.Append(id, "Remove", name)
666                wx.EVT_MENU(self, id, self._onRemove)
667                if not plot.is_data:
668                    id = wx.NewId()
669                    plot_menu.Append(id, '&Freeze', name)
670                    wx.EVT_MENU(self, id, self.onFreeze)
671                plot_menu.AppendSeparator()   
672                symbol_menu = wx.Menu()
673               
674                if plot.is_data:
675                    id = wx.NewId()
676                    self.hide_menu = plot_menu.Append(id, 
677                                                    "Hide Error Bar", name)
678       
679                    if plot.dy is not None and plot.dy != []:
680                        if plot.hide_error :
681                            self.hide_menu.SetText('Show Error Bar')
682                        else:
683                            self.hide_menu.SetText('Hide Error Bar')
684                    else:
685                        self.hide_menu.Enable(False)
686                    wx.EVT_MENU(self, id, self._ontoggle_hide_error)
687               
688                    plot_menu.AppendSeparator()
689
690                id = wx.NewId()
691                plot_menu.Append(id, '&Modify Plot Property', name)
692                wx.EVT_MENU(self, id, self.createAppDialog)
693
694
695
696            id = wx.NewId()
697            #plot_menu.SetTitle(name)
698            self._slicerpop.AppendMenu(id, '&%s'% name, plot_menu)
699            # Option to hide
700            #TODO: implement functionality to hide a plottable (legend click)
701        if not self.graph.selected_plottable in self.plots: 
702            self._slicerpop.AppendSeparator()
703            loc_menu = wx.Menu()
704            for label in self._loc_labels:
705                id = wx.NewId()
706                loc_menu.Append(id, str(label), str(label))
707                wx.EVT_MENU(self, id, self.onChangeLegendLoc)
708           
709            id = wx.NewId()
710            self._slicerpop.Append(id, '&Modify Graph Appearance',
711                                   'Modify graph appearance')
712            wx.EVT_MENU(self, id, self.modifyGraphAppearance)
713            self._slicerpop.AppendSeparator()
714
715           
716            if self.position != None:
717                id = wx.NewId()
718                self._slicerpop.Append(id, '&Add Text')
719                wx.EVT_MENU(self, id, self._on_addtext)
720                id = wx.NewId()
721                self._slicerpop.Append(id, '&Remove Text')
722                wx.EVT_MENU(self, id, self._on_removetext)
723                self._slicerpop.AppendSeparator()
724            id = wx.NewId()
725            self._slicerpop.Append(id, '&Change Scale')
726            wx.EVT_MENU(self, id, self._onProperties)
727            self._slicerpop.AppendSeparator()
728            id = wx.NewId()
729            self._slicerpop.Append(id, '&Reset Graph Range')
730            wx.EVT_MENU(self, id, self.onResetGraph) 
731           
732            if self.parent.ClassName.count('wxDialog') == 0:   
733                self._slicerpop.AppendSeparator()
734                id = wx.NewId()
735                self._slicerpop.Append(id, '&Window Title')
736                wx.EVT_MENU(self, id, self.onChangeCaption)
737        try:
738            pos_evt = event.GetPosition()
739            pos = self.ScreenToClient(pos_evt)
740        except:
741            pos_x, pos_y = self.toolbar.GetPositionTuple()
742            pos = (pos_x, pos_y + 5)
743        self.PopupMenu(self._slicerpop, pos)
744           
745    def onFreeze(self, event):
746        """
747        on Freeze data
748        """
749        menu = event.GetEventObject()
750        id = event.GetId()
751        self.set_selected_from_menu(menu, id)
752        plot = self.plots[self.graph.selected_plottable]
753        self.parent.onfreeze([plot.id])
754       
755                       
756    def _onSave(self, evt):
757        """
758        Save a data set to a text file
759       
760        :param evt: Menu event
761       
762        """
763        menu = evt.GetEventObject()
764        id = evt.GetId()
765        self.set_selected_from_menu(menu, id)
766        data = self.plots[self.graph.selected_plottable]
767        default_name = data.label
768        if default_name.count('.') > 0:
769            default_name = default_name.split('.')[0]
770        default_name += "_out"
771        if self.parent != None:
772            self.parent.save_data1d(data, default_name)
773
774                       
775    def _onDataShow(self, evt):
776        """
777        Show the data set in text
778       
779        :param evt: Menu event
780       
781        """
782        menu = evt.GetEventObject()
783        id = evt.GetId()
784        self.set_selected_from_menu(menu, id)
785        data = self.plots[self.graph.selected_plottable]
786        default_name = data.label
787        if default_name.count('.') > 0:
788            default_name = default_name.split('.')[0]
789        #default_name += "_out"
790        if self.parent != None:
791            self.parent.show_data1d(data, default_name)
792           
793    def _add_more_tool(self):
794        """
795        Add refresh, add/hide button in the tool bar
796        """
797        return
798        if self.parent.__class__.__name__ != 'ViewerFrame':
799            return
800        self.toolbar.AddSeparator()
801        id_hide = wx.NewId()
802        hide = wx.Bitmap(GUIFRAME_ICON.HIDE_ID_PATH, wx.BITMAP_TYPE_PNG)
803        self.toolbar.AddSimpleTool(id_hide, hide, 'Hide', 'Hide')
804        self.toolbar.Realize()
805        wx.EVT_TOOL(self, id_hide,  self._on_hide)
806       
807    def _on_hide(self, event):
808        """
809        Hides the plot when button is pressed
810        """     
811        if self.parent is not None:
812            self.parent.hide_panel(self.uid)
813
814    def on_close(self, event):
815        """
816        On Close Event
817        """
818        ID = self.uid
819        self.parent.delete_panel(ID)
820   
821    def createAppDialog(self, event):
822        """
823        Create the custom dialog for fit appearance modification
824        """
825        menu = event.GetEventObject()
826        id = event.GetId()
827        self.set_selected_from_menu(menu, id)
828        self.appearance_selected_plot = \
829                        self.plots[self.graph.selected_plottable]
830        # find current properties
831        curr_color = self.appearance_selected_plot.custom_color
832        curr_symbol = self.appearance_selected_plot.symbol
833        curr_size = self.appearance_selected_plot.markersize
834        curr_label = self.appearance_selected_plot.label
835
836        if curr_color == None:
837            curr_color = self._color_labels['Blue']
838            curr_symbol = 13
839
840        self.appD = appearanceDialog(self, 'Modify Plot Property')
841        icon = self.parent.GetIcon()
842        self.appD.SetIcon(icon)
843        self.appD.set_defaults(float(curr_size), int(curr_color), 
844                    str(appearanceDialog.find_key(self.get_symbol_label(), 
845                    int(curr_symbol))), curr_label)
846        self.appD.Bind(wx.EVT_CLOSE, self.on_AppDialog_close)   
847
848    def on_AppDialog_close(self, event):
849        """
850        on_Modify Plot Property_close
851        """
852        if(self.appD.okay_clicked == True):
853            # returns (size,color,symbol,datalabel)
854            info = self.appD.get_current_values() 
855            self.appearance_selected_plot.custom_color = \
856                        self._color_labels[info[1].encode('ascii', 'ignore')]
857
858            self.appearance_selected_plot.markersize = float(info[0])
859            self.appearance_selected_plot.symbol = \
860                        self.get_symbol_label()[info[2]] 
861            self.appearance_selected_plot.label = str(info[3])
862
863            #pos = self.parent._window_menu.FindItem(self.window_caption)
864            #helpString = 'Show/Hide Graph: '
865            #for plot in  self.plots.itervalues():
866            #    helpString += (' ' + str(plot.label) + ';')
867            #    self.parent._window_menu.SetHelpString(pos, helpString)
868            #    self._is_changed_legend_label = True
869               
870        self.appD.Destroy()
871        self._check_zoom_plot()
872
873
874    def modifyGraphAppearance(self, event):
875        """
876        On Modify Graph Appearance
877        """
878        self.graphApp = graphAppearance(self, 'Modify Graph Appearance')
879        icon = self.parent.GetIcon()
880        self.graphApp.SetIcon(icon)
881        self.graphApp.setDefaults(self.grid_on, self.legend_on, 
882                                  self.xaxis_label, self.yaxis_label, 
883                                  self.xaxis_unit, self.yaxis_unit, 
884                                  self.xaxis_font, self.yaxis_font, 
885                                  find_key(self.get_loc_label(), 
886                                  self.legendLoc), 
887                                  self.xcolor, self.ycolor, 
888                                  self.is_xtick, self.is_ytick)
889        self.graphApp.Bind(wx.EVT_CLOSE, self.on_graphApp_close)
890   
891
892    def on_graphApp_close(self, event):
893        """
894        Gets values from graph appearance dialog and sends them off
895        to modify the plot
896        """
897        graph_app = self.graphApp
898        toggle_grid = graph_app.get_togglegrid()
899        legend_loc = graph_app.get_legend_loc()
900        toggle_legend = graph_app.get_togglelegend()
901       
902        self.onGridOnOff(toggle_grid )
903        self.ChangeLegendLoc(legend_loc)
904        self.onLegend(toggle_legend)
905
906        self.xaxis_label = graph_app.get_xlab()
907        self.yaxis_label = graph_app.get_ylab()
908        self.xaxis_unit = graph_app.get_xunit()
909        self.yaxis_unit = graph_app.get_yunit()
910        self.xaxis_font = graph_app.get_xfont()
911        self.yaxis_font = graph_app.get_yfont()
912        self.is_xtick =  graph_app.get_xtick_check()
913        self.is_ytick =  graph_app.get_ytick_check()
914        if self.is_xtick:
915            self.xaxis_tick = self.xaxis_font
916        if self.is_ytick:
917            self.yaxis_tick = self.yaxis_font
918
919        self.xaxis(self.xaxis_label, self.xaxis_unit, 
920                   graph_app.get_xfont(), graph_app.get_xcolor(), 
921                   self.xaxis_tick)
922        self.yaxis(self.yaxis_label, self.yaxis_unit, 
923                   graph_app.get_yfont(), graph_app.get_ycolor(),
924                   self.yaxis_tick)
925
926        graph_app.Destroy()
Note: See TracBrowser for help on using the repository browser.