source: sasview/src/examples/test_panel2D.py @ c31dcdb1

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 c31dcdb1 was d7bb526, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 9 years ago

Refactored plottools into sasgui

  • Property mode set to 100644
File size: 9.1 KB
Line 
1"""
2    Test application that uses plottools
3    This application uses most of the functionality required by the SAS group
4    and should be treated as a test-case representative of that use.
5   
6    The following is a checklist of functionality to look for while testing:
7   
8    1- Start the application: the graph should be empty with a white background.
9        The status bar should read "This is a data viewer".
10    2- From the "File" menu, click "Add data": Three data sets should be plotted:
11        - A line called Theory curve, in blue.
12        - A series of green points with errors above that line, called Data set 1.
13        - A series of red points with errors below that line, called Data set 2.
14    3- Hovering over any plotted data will highlight the whole data set or line in yellow.
15    4- Left-clicking on the graph and dragging will drag the graph.
16    5- Using the mouse wheel will zoom in and out of the graph.
17    6- Right-clicking on the graph when no curve is highlighted will
18        pop up the context menu:
19        - "Save image" will pop up a save dialog to save an image.
20        - "Reset graph" will reset the graph to its original appearance after it
21            has been dragged around or zoomed in or out.
22        - "Change scale" will pop up a scale dialog with which the axes can
23            be transformed. Each transformation choice should work.
24    7- Right-clicking on the graph when a curve is highlighted will
25        pop up the context menu describe above, to which an item called
26        "Linear fit to [name of the data set]" is added.
27   
28        Selecting a linear fit to data sets 1 or 2 will pop up a fit dialog.
29        After fitting, the fit result will appear will be shown in the dialog
30        and the fit curve will appear on the plot and should follow the data.
31   
32        It is possible to interact with the graph when the fit dialog is up.
33       
34        Selecting a linear fit to the theory curve will produce a message
35        on the status bar saying: "Can't fit a theory curve"
36     
37"""
38import wx
39from sas.sasgui.plottools.PlotPanel import PlotPanel
40from sas.sasgui.plottools.plottables import Data1D, Theory1D, Data2D
41import  sys,os
42import numpy
43import random, math
44
45
46class SASplotpanel(PlotPanel):
47   
48    def __init__(self, parent, id = -1, color = None,\
49        dpi = None, **kwargs):
50        PlotPanel.__init__(self, parent, id=id, color=color, dpi=dpi, **kwargs)
51       
52        # Keep track of the parent Frame
53        self.parent = parent
54       
55        # Internal list of plottable names (because graph
56        # doesn't have a dictionary of handles for the plottables)
57        self.plots = {}
58       
59    def add_plottable(self, plot):
60        self.plots[plot.name] = plot
61       
62        self.graph.add(plot)
63        self.graph.xaxis('\\rm{q} ', 'A^{-1}')
64        self.graph.yaxis("\\rm{Intensity} ","cm^{-1}")
65        self.onResetGraph(None)
66       
67    def add_image(self, plot):
68        self.plots[plot.name] = plot
69       
70        self.graph.add(plot)
71        self.graph.xaxis('\\rm{q} ', 'A^{-1}')
72        self.graph.yaxis("\\rm{Intensity} ","cm^{-1}")
73        self.graph.render(self)
74        self.subplot.figure.canvas.draw_idle()
75        #self.onResetGraph(None)
76    def plottable_selected(self, id):
77        PlotPanel.plottable_selected(self, id)
78        if id is not None:
79            self.parent.SetStatusText("Hovering over %s" % self.graph.selected_plottable)
80        else:
81            self.parent.SetStatusText("")
82   
83    def onContextMenu(self, event):
84        """
85            Default context menu for a plot panel
86        """
87        # Slicer plot popup menu
88        id = wx.NewId()
89        slicerpop = wx.Menu()
90        slicerpop.Append(id,'&Save image', 'Save image as PNG')
91        wx.EVT_MENU(self, id, self.onSaveImage)
92       
93        slicerpop.AppendSeparator()
94        id = wx.NewId()
95        slicerpop.Append(id, '&Change scale')
96        wx.EVT_MENU(self, id, self._onProperties)
97       
98        id = wx.NewId()
99        slicerpop.Append(id, '&Reset Graph')
100        wx.EVT_MENU(self, id, self.onResetGraph)
101       
102        id = wx.NewId()
103        slicerpop.Append(id, '&Toggle Linear/Log scale')
104        wx.EVT_MENU(self, id, self._onToggleScale)
105       
106        if self.graph.selected_plottable in self.plots:
107            # Careful here: Message to status bar
108            self.parent.SetStatusText("Fit a line to %s" % self.graph.selected_plottable)
109            id = wx.NewId()
110            slicerpop.AppendSeparator()
111            slicerpop.Append(id, '&Linear Fit to %s' % self.graph.selected_plottable )
112            wx.EVT_MENU(self, id, self.onFitting)
113       
114        pos = event.GetPosition()
115        pos = self.ScreenToClient(pos)
116        self.PopupMenu(slicerpop, pos)
117       
118    def onFitting(self, event):
119        if self.graph.selected_plottable is not None:
120            if self.plots[self.graph.selected_plottable].__class__.__name__ == 'Data1D':
121                PlotPanel.onFitting(self, event)     
122            else:
123                self.parent.SetStatusText("Can't fit a theory curve")
124
125class ViewerFrame(wx.Frame):
126    """
127        Add comment
128    """
129    def __init__(self, parent, id, title):
130        """
131            comment
132            @param parent: parent panel/container
133        """
134        # Initialize the Frame object
135        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(950,850))
136       
137        # Panel for 1D plot
138        self.plotpanel    = SASplotpanel(self, -1, style=wx.RAISED_BORDER)
139
140        # Set up the menu
141        self._setup_menus()
142     
143        # Set up the layout
144        self._setup_layout()
145               
146        # Register the close event so it calls our own method
147        wx.EVT_CLOSE(self, self._onClose)
148       
149       
150    def _setup_layout(self):
151        """
152            Set up the layout
153        """
154        # Status bar
155        self.sb = self.CreateStatusBar()
156        self.SetStatusText("This is a data viewer")
157       
158        # Two columns of panels
159        sizer = wx.GridBagSizer(0,0)
160       
161        sizer.Add(self.plotpanel, (0,0), (1,1),   flag=wx.EXPAND | wx.ALL, border=0)
162        sizer.AddGrowableRow(0)
163        sizer.AddGrowableCol(0)
164   
165        self.SetSizer(sizer)
166        self.Centre()
167               
168    def _setup_menus(self):
169        """
170            Set up the application menus
171        """
172       
173        # Menu
174        menubar = wx.MenuBar()
175        # File menu
176        filemenu = wx.Menu()
177       
178        # Quit
179        id = wx.NewId()
180        filemenu.Append(id,'&Quit', 'Exit')
181        wx.EVT_MENU(self, id, self._onClose)
182       
183        # New plot
184        id = wx.NewId()
185        filemenu.Append(id,'&Add data', 'Add a new curve to the plot')
186        wx.EVT_MENU(self, id, self._add_data)
187       
188        id = wx.NewId()
189        filemenu.Append(id,'&Load data 2D', 'load data 2D')
190        wx.EVT_MENU(self, id, self.OnLoad)
191        # Add sub menus
192        menubar.Append(filemenu, '&File')
193        self.SetMenuBar(menubar)
194       
195       
196    def OnLoad(self,event):
197        path = None
198        dlg = wx.FileDialog(None, "Choose a file", os.getcwd(), "", "*", wx.OPEN)
199        if dlg.ShowModal() == wx.ID_OK:
200            path = dlg.GetPath()
201            mypath = os.path.basename(path)
202            from sas.sascalc.dataloader.loader import  Loader
203           
204            #Instantiate a loader
205            L=Loader()
206           
207            #Recieves data
208            try:
209                output=L.load(path)
210            except:
211                raise
212           
213            newplot=Data2D(image=output.data)
214            newplot.setValues(output)
215            self.plotpanel.add_image(newplot)
216           
217               
218        dlg.Destroy()
219       
220    def _onClose(self, event):
221        """
222        """
223        wx.Exit()
224        sys.exit()
225           
226    def _add_data(self, event):
227        data_len = 50
228        x  = numpy.zeros(data_len)
229        y  = numpy.zeros(data_len)
230        x2  = numpy.zeros(data_len)
231        y2  = numpy.zeros(data_len)
232        dy2  = numpy.zeros(data_len)
233        x3  = numpy.zeros(data_len)
234        y3  = numpy.zeros(data_len)
235        dy3  = numpy.zeros(data_len)
236        for i in range(len(x)):
237            x[i] = i
238            x2[i] = i-0.1+0.2*random.random()
239            x3[i] = i-0.1+0.2*random.random()
240            y[i] = 0.5*(i+random.random())
241            y2[i] = i+random.random()
242            dy2[i] = math.sqrt(y2[i]) 
243            y3[i] = 0.3*(i+random.random())
244            dy3[i] = math.sqrt(y3[i]) 
245           
246        newplot = Theory1D(x=x, y=y)
247        newplot.name = "Theory curve"
248        self.plotpanel.add_plottable(newplot)
249       
250        newplot = Data1D(x=x2, y=y2, dy=dy2)
251        newplot.name = "Data set 1"
252        self.plotpanel.add_plottable(newplot)
253       
254        newplot = Data1D(x=x3, y=y3, dy=dy3)
255        newplot.name = "Data set 2"
256        self.plotpanel.add_plottable(newplot)
257           
258 
259class ViewApp(wx.App):
260    def OnInit(self):
261        frame = ViewerFrame(None, -1, 'testView')   
262        frame.Show(True)
263        self.SetTopWindow(frame)
264       
265        return True
266       
267
268if __name__ == "__main__": 
269    app = ViewApp(0)
270    app.MainLoop()       
271           
Note: See TracBrowser for help on using the repository browser.