source: sasview/src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter1D.py @ 3901e7c

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.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 3901e7c was 3901e7c, checked in by lewis, 8 years ago

Allow inputting of qmin and qmax, and plot them on the graph as vertical lines

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