source: sasview/guiframe/local_perspectives/plotting/plotting.py @ 14b8154

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 14b8154 was 383189f9, checked in by Mathieu Doucet <doucetm@…>, 16 years ago

Added plot group ID

  • Property mode set to 100644
File size: 8.7 KB
Line 
1"""
2This software was developed by the University of Tennessee as part of the
3Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
4project funded by the US National Science Foundation.
5
6See the license text in license.txt
7
8copyright 2008, University of Tennessee
9"""
10
11
12import wx
13import sys
14from sans.guitools.PlotPanel import PlotPanel
15from sans.guitools.plottables import Graph
16from sans.guicomm.events import EVT_NEW_PLOT
17
18class PanelMenu(wx.Menu):
19    plots = None
20   
21    def set_plots(self, plots):
22        self.plots = plots
23   
24
25class View1DPanel(PlotPanel):
26    """
27        Plot panel for use with the GUI manager
28    """
29   
30    ## Internal name for the AUI manager
31    window_name = "plotpanel"
32    ## Title to appear on top of the window
33    window_caption = "Plot Panel"
34    ## Flag to tell the GUI manager that this panel is not
35    #  tied to any perspective
36    ALWAYS_ON = True
37    ## Group ID
38    group_id = None
39   
40    def __init__(self, parent, id = -1, color = None,\
41        dpi = None, style = wx.NO_FULL_REPAINT_ON_RESIZE, **kwargs):
42        """
43            Initialize the panel
44        """
45        PlotPanel.__init__(self, parent, id = id, style = style, **kwargs)
46       
47        ## Reference to the parent window
48        self.parent = parent
49        ## Plottables
50        self.plots = {}
51       
52        ## Unique ID (from gui_manager)
53        self.uid = None
54       
55        ## Graph       
56        self.graph = Graph()
57        self.graph.xaxis("\\rm{Q}", 'A^{-1}')
58        self.graph.yaxis("\\rm{Intensity} ","cm^{-1}")
59        self.graph.render(self)
60       
61    def _onEVT_1DREPLOT(self, event):
62        """
63            Data is ready to be displayed
64            @param event: data event
65        """
66        #TODO: Check for existence of plot attribute
67       
68        is_new = True
69        if event.plot.name in self.plots.keys():
70            is_new = False
71       
72        if is_new:
73            self.plots[event.plot.name] = event.plot
74            self.graph.add(self.plots[event.plot.name])
75        else:
76            self.plots[event.plot.name].x = event.plot.x   
77            self.plots[event.plot.name].y = event.plot.y   
78            self.plots[event.plot.name].dy = event.plot.dy 
79            if hasattr(event.plot, 'dx') and hasattr(self.plots[event.plot.name], 'dx'):
80                self.plots[event.plot.name].dx = event.plot.dx   
81 
82       
83        # Check axis labels
84        #TODO: Should re-factor this
85        if event.plot._xunit != self.graph.prop["xunit"]:
86            self.graph.xaxis(event.plot._xaxis, event.plot._xunit)
87           
88        if event.plot._yunit != self.graph.prop["yunit"]:
89            self.graph.yaxis(event.plot._yaxis, event.plot._yunit)
90     
91        self.graph.render(self)
92        self.subplot.figure.canvas.draw_idle()
93
94    def onContextMenu(self, event):
95        """
96            1D plot context menu
97            @param event: wx context event
98        """
99        #slicerpop = wx.Menu()
100        slicerpop = PanelMenu()
101        slicerpop.set_plots(self.plots)
102               
103        # Various plot options
104        id = wx.NewId()
105        slicerpop.Append(id,'&Save image', 'Save image as PNG')
106        wx.EVT_MENU(self, id, self.onSaveImage)
107       
108        slicerpop.AppendSeparator()
109        item_list = self.parent.get_context_menu()
110        if not item_list==None:
111            for item in item_list:
112                try:
113                    id = wx.NewId()
114                    slicerpop.Append(id, item[0], item[1])
115                    wx.EVT_MENU(self, id, item[2])
116                except:
117                    print sys.exc_value
118                    print RuntimeError, "View1DPanel.onContextMenu: bad menu item"
119       
120        slicerpop.AppendSeparator()
121       
122        id = wx.NewId()
123        slicerpop.Append(id, '&Toggle Linear/Log scale')
124        wx.EVT_MENU(self, id, self._onToggleScale)
125
126        pos = event.GetPosition()
127        pos = self.ScreenToClient(pos)
128        self.PopupMenu(slicerpop, pos)
129   
130    def _onToggleScale(self, event):
131        if self.get_yscale() == 'log':
132            self.set_yscale('linear')
133        else:
134            self.set_yscale('log')
135        self.subplot.figure.canvas.draw_idle()   
136   
137class Plugin:
138    """
139        Plug-in class to be instantiated by the GUI manager
140    """
141   
142    def __init__(self):
143        """
144            Initialize the plug-in
145        """
146        ## Plug-in name
147        self.sub_menu = "Plotting"
148       
149        ## Reference to the parent window
150        self.parent = None
151       
152        ## List of panels for the simulation perspective (names)
153        self.perspective = []
154       
155        ## Plot panels
156        self.plot_panels = []
157       
158
159    def populate_menu(self, id, parent):
160        """
161            Create a 'Plot' menu to list the panels
162            available for displaying
163            @param id: next available unique ID for wx events
164            @param parent: parent window
165        """
166        self.menu = wx.Menu()
167        return [(id, self.menu, "Plot")]
168   
169       
170    def get_panels(self, parent):
171        """
172            Create and return a list of panel objects
173        """
174        ## Save a reference to the parent
175        self.parent = parent
176        # Connect to plotting events
177        self.parent.Bind(EVT_NEW_PLOT, self._on_plot_event)
178       
179        # We have no initial panels for this plug-in
180        return []
181   
182    def get_perspective(self):
183        """
184            Get the list of panel names for this perspective
185        """
186        return self.perspective
187   
188    def on_perspective(self, event):
189        """
190            Call back function for the perspective menu item.
191            We notify the parent window that the perspective
192            has changed.
193            @param event: menu event
194        """
195        self.parent.set_perspective(self.perspective)
196   
197    def post_init(self):
198        """
199            Post initialization call back to close the loose ends
200            [Somehow openGL needs this call]
201        """
202        pass
203   
204    def _on_show_panel(self, event):
205        print "_on_show_panel"
206   
207    def _on_plot_event(self, event):
208        """
209            A new plottable is being shipped to the plotting plug-in.
210            Check whether we have a panel to put in on, or create
211            a new one
212            @param event: EVT_NEW_PLOT event
213        """
214        # Check whether we already have a graph with the same units
215        # as the plottable we just received.
216        is_available = False
217        for panel in self.plot_panels:
218            if event.plot._xunit == panel.graph.prop["xunit"] \
219            and event.plot._yunit == panel.graph.prop["yunit"]:
220                if hasattr(event.plot, "group_id"):
221                    if not event.plot.group_id==None \
222                        and event.plot.group_id==panel.group_id:
223                        is_available = True
224                        panel._onEVT_1DREPLOT(event)
225                        self.parent.show_panel(panel.uid)
226                else:
227                    # Check that the plot panel has no group ID
228                    if panel.group_id==None:
229                        is_available = True
230                        panel._onEVT_1DREPLOT(event)
231                        self.parent.show_panel(panel.uid)
232       
233        # Create a new plot panel if none was available       
234        if not is_available:
235            new_panel = View1DPanel(self.parent, -1, style=wx.RAISED_BORDER)
236            # Set group ID if available
237            group_id_str = ''
238            if hasattr(event.plot, "group_id"):
239                if not event.plot.group_id==None:
240                    new_panel.group_id = event.plot.group_id
241                    group_id_str = ' [%s]' % event.plot.group_id
242           
243            if hasattr(event, "title"):
244                new_panel.window_caption = event.title
245                new_panel.window_name = event.title
246                #new_panel.window_caption = event.title+group_id_str
247                #new_panel.window_name = event.title+group_id_str
248           
249            event_id = self.parent.popup_panel(new_panel)
250            self.menu.Append(event_id, new_panel.window_caption, 
251                             "Show %s plot panel" % new_panel.window_caption)
252           
253            # Set UID to allow us to reference the panel later
254            new_panel.uid = event_id
255           
256            # Ship the plottable to its panel
257            new_panel._onEVT_1DREPLOT(event)
258            self.plot_panels.append(new_panel)       
259           
260        return
261       
Note: See TracBrowser for help on using the repository browser.