source: sasview/src/sas/guiframe/local_perspectives/plotting/Plotter1D.py @ f21d496

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 f21d496 was b99a4552, checked in by Paul Kienzle <pkienzle@…>, 9 years ago

avoid moving qrange bars beyond the edge of the data. Fixes #417

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