source: sasview/plottools/examples/test_panel2D.py @ dac6869

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 dac6869 was 82a54b8, checked in by Mathieu Doucet <doucetm@…>, 13 years ago

adding plottools Part 2

  • Property mode set to 100644
File size: 9.2 KB
Line 
1"""
2    Test application that uses plottools
3    This application uses most of the functionality required by the SANS 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 danse.common.plottools.PlotPanel import PlotPanel
40from danse.common.plottools.plottables import Plottable, Graph, Data1D, Theory1D,Data2D
41import  sys,os
42import numpy
43import random, math
44
45
46class SANSplotpanel(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    = SANSplotpanel(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 danse.common.plottools.plottables import Data2D
203            from DataLoader.loader import  Loader
204           
205            #Instantiate a loader
206            L=Loader()
207           
208            #Recieves data
209            try:
210                output=L.load(path)
211            except:
212                raise
213           
214            newplot=Data2D(image=output.data)
215            newplot.setValues(output)
216            self.plotpanel.add_image(newplot)
217           
218               
219        dlg.Destroy()
220       
221    def _onClose(self, event):
222        """
223        """
224        wx.Exit()
225        sys.exit()
226           
227    def _add_data(self, event):
228        data_len = 50
229        x  = numpy.zeros(data_len)
230        y  = numpy.zeros(data_len)
231        x2  = numpy.zeros(data_len)
232        y2  = numpy.zeros(data_len)
233        dy2  = numpy.zeros(data_len)
234        x3  = numpy.zeros(data_len)
235        y3  = numpy.zeros(data_len)
236        dy3  = numpy.zeros(data_len)
237        for i in range(len(x)):
238            x[i] = i
239            x2[i] = i-0.1+0.2*random.random()
240            x3[i] = i-0.1+0.2*random.random()
241            y[i] = 0.5*(i+random.random())
242            y2[i] = i+random.random()
243            dy2[i] = math.sqrt(y2[i]) 
244            y3[i] = 0.3*(i+random.random())
245            dy3[i] = math.sqrt(y3[i]) 
246           
247        newplot = Theory1D(x=x, y=y)
248        newplot.name = "Theory curve"
249        self.plotpanel.add_plottable(newplot)
250       
251        newplot = Data1D(x=x2, y=y2, dy=dy2)
252        newplot.name = "Data set 1"
253        self.plotpanel.add_plottable(newplot)
254       
255        newplot = Data1D(x=x3, y=y3, dy=dy3)
256        newplot.name = "Data set 2"
257        self.plotpanel.add_plottable(newplot)
258           
259 
260class ViewApp(wx.App):
261    def OnInit(self):
262        frame = ViewerFrame(None, -1, 'testView')   
263        frame.Show(True)
264        self.SetTopWindow(frame)
265       
266        return True
267       
268
269if __name__ == "__main__": 
270    app = ViewApp(0)
271    app.MainLoop()       
272           
Note: See TracBrowser for help on using the repository browser.