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

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 062ebef was cafa75f, checked in by pkienzle, 11 years ago

support old and new versions of matplotlib

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