source: sasview/guiframe/local_perspectives/plotting/Plotter1D.py @ 97f0c39b

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 97f0c39b was d468daa, checked in by Gervaise Alina <gervyh@…>, 16 years ago

print stament removed

  • Property mode set to 100644
File size: 12.8 KB
RevLine 
[1bf33c1]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
[0d9dae8]14import pylab
15
[1bf33c1]16import danse.common.plottools
17from danse.common.plottools.PlotPanel import PlotPanel
18from danse.common.plottools.plottables import Graph,Data1D
19from sans.guicomm.events import EVT_NEW_PLOT
[0d9dae8]20from sans.guicomm.events import StatusEvent ,NewPlotEvent,SlicerEvent
21from sans.guiframe.utils import PanelMenu
[1bf33c1]22
23from binder import BindArtist
24
[0d9dae8]25
26DEFAULT_QMAX = 0.05
[1bf33c1]27DEFAULT_QSTEP = 0.001
28DEFAULT_BEAM = 0.005
29BIN_WIDTH =1
30
[0d9dae8]31
[1bf33c1]32class ModelPanel1D(PlotPanel):
33    """
34        Plot panel for use with the GUI manager
35    """
36   
37    ## Internal name for the AUI manager
38    window_name = "plotpanel"
39    ## Title to appear on top of the window
40    window_caption = "Plot Panel"
41    ## Flag to tell the GUI manager that this panel is not
42    #  tied to any perspective
43    ALWAYS_ON = True
44    ## Group ID
45    group_id = None
46   
47    def __init__(self, parent, id = -1, color = None,\
48        dpi = None, style = wx.NO_FULL_REPAINT_ON_RESIZE, **kwargs):
49        """
50            Initialize the panel
51        """
52        PlotPanel.__init__(self, parent, id = id, style = style, **kwargs)
53       
54        ## Reference to the parent window
55        self.parent = parent
56        ## Plottables
57        self.plots = {}
58       
59        ## Unique ID (from gui_manager)
60        self.uid = None
61       
62        ## Action IDs for internal call-backs
63        self.action_ids = {}
64       
65        ## Graph       
66        self.graph = Graph()
67        self.graph.xaxis("\\rm{Q}", 'A^{-1}')
68        self.graph.yaxis("\\rm{Intensity} ","cm^{-1}")
69        self.graph.render(self)
70   
71    def _reset(self):
72        """
73            Resets internal data and graph
74        """   
75        self.graph.reset()
76        self.plots      = {}
77        self.action_ids = {}
78   
79    def _onEVT_1DREPLOT(self, event):
80        """
81            Data is ready to be displayed
82            @param event: data event
83        """
[ffd23b5]84       
[1bf33c1]85        #TODO: Check for existence of plot attribute
86
87        # Check whether this is a replot. If we ask for a replot
88        # and the plottable no longer exists, ignore the event.
89        if hasattr(event, "update") and event.update==True \
90            and event.plot.name not in self.plots.keys():
91            return
92       
93        if hasattr(event, "reset"):
94            self._reset()
95       
96        is_new = True
97        if event.plot.name in self.plots.keys():
98            # Check whether the class of plottable changed
99            if not event.plot.__class__==self.plots[event.plot.name].__class__:
[ab8f936]100                #overwrite a plottable using the same name
[1bf33c1]101                self.graph.delete(self.plots[event.plot.name])
102            else:
[ab8f936]103                # plottable is already draw on the panel
[1bf33c1]104                is_new = False
[ffd23b5]105       
106           
[ab8f936]107           
[1bf33c1]108        if is_new:
[ab8f936]109            # a new plottable overwrites a plotted one  using the same id
110            for plottable in self.plots.itervalues():
111                if event.plot.id==plottable.id :
112                    self.graph.delete(plottable)
113           
[1bf33c1]114            self.plots[event.plot.name] = event.plot
115            self.graph.add(self.plots[event.plot.name])
116        else:
[ab8f936]117            #replot the graph
[1bf33c1]118            self.plots[event.plot.name].x = event.plot.x   
119            self.plots[event.plot.name].y = event.plot.y   
120            self.plots[event.plot.name].dy = event.plot.dy 
121            if hasattr(event.plot, 'dx') and hasattr(self.plots[event.plot.name], 'dx'):
122                self.plots[event.plot.name].dx = event.plot.dx   
123 
124       
125        # Check axis labels
126        #TODO: Should re-factor this
127        #if event.plot._xunit != self.graph.prop["xunit"]:
[ffd23b5]128       
[1bf33c1]129        self.graph.xaxis(event.plot._xaxis, event.plot._xunit)
130           
131        #if event.plot._yunit != self.graph.prop["yunit"]:
132        self.graph.yaxis(event.plot._yaxis, event.plot._yunit)
133     
134        # Set the view scale for all plots
[ef0c170]135       
[1bf33c1]136        self._onEVT_FUNC_PROPERTY()
[ef0c170]137   
[1bf33c1]138        self.graph.render(self)
139        self.subplot.figure.canvas.draw_idle()
140
141    def onLeftDown(self,event): 
142        """ left button down and ready to drag"""
143           
144        PlotPanel.onLeftDown(self, event)
145        ax = event.inaxes
146        if ax != None:
147            position = "x: %8.3g    y: %8.3g" % (event.xdata, event.ydata)
148            wx.PostEvent(self.parent, StatusEvent(status=position))
149
150    def _onRemove(self, event):
151        """
152        """
153        if not self.graph.selected_plottable == None:
[d468daa]154            #print self.graph.selected_plottable
[1bf33c1]155            self.graph.delete(self.plots[self.graph.selected_plottable])
156            del self.plots[self.graph.selected_plottable]
157            self.graph.render(self)
158            self.subplot.figure.canvas.draw_idle()   
159           
160
161    def onContextMenu(self, event):
162        """
163            1D plot context menu
164            @param event: wx context event
165        """
166        #slicerpop = wx.Menu()
167        slicerpop = PanelMenu()
168        slicerpop.set_plots(self.plots)
169        slicerpop.set_graph(self.graph)
170               
171        # Option to save the data displayed
172       
173        #for plot in self.graph.plottables:
174        if self.graph.selected_plottable in self.plots:
175            plot = self.plots[self.graph.selected_plottable]
176            id = wx.NewId()
177            name = plot.name
178            slicerpop.Append(id, "&Save %s points" % name)
179            self.action_ids[str(id)] = plot
180            wx.EVT_MENU(self, id, self._onSave)
181               
182            # Option to delete plottable
183            id = wx.NewId()
184            slicerpop.Append(id, "Remove %s curve" % name)
185            self.action_ids[str(id)] = plot
186            wx.EVT_MENU(self, id, self._onRemove)
[d468daa]187           
[1bf33c1]188            # Option to hide
189            #TODO: implement functionality to hide a plottable (legend click)
[d468daa]190           
[1bf33c1]191               
192        # Various plot options
193        id = wx.NewId()
194        slicerpop.Append(id,'&Save image', 'Save image as PNG')
195        wx.EVT_MENU(self, id, self.onSaveImage)
196       
[d468daa]197        slicerpop.AppendSeparator()
[1bf33c1]198        item_list = self.parent.get_context_menu(self.graph)
[d468daa]199        #print "item_list",item_list
[1bf33c1]200        if (not item_list==None) and (not len(item_list)==0):
201                for item in item_list:
202                    try:
203                        id = wx.NewId()
204                        slicerpop.Append(id, item[0], item[1])
205                        wx.EVT_MENU(self, id, item[2])
206                    except:
[d468daa]207                        pass
208                        #print sys.exc_value
209                        #print RuntimeError, "View1DPanel.onContextMenu: bad menu item"
[1bf33c1]210       
[d468daa]211       
[1bf33c1]212        if self.graph.selected_plottable in self.plots:
213            if self.plots[self.graph.selected_plottable].__class__.__name__=="Theory1D":
214                id = wx.NewId()
215                slicerpop.Append(id, '&Add errors to data')
[ffd23b5]216                #print "panel scale before  ",self.xLabel, self.yLabel
217                #print "cyllinder before adding error", self.plots[self.graph.selected_plottable].x
[1bf33c1]218                wx.EVT_MENU(self, id, self._on_add_errors)
219            else:
220                id = wx.NewId()
221                slicerpop.Append(id, '&Linear fit')
222                wx.EVT_MENU(self, id, self.onFitting)
223               
[d468daa]224        slicerpop.AppendSeparator()
[1bf33c1]225        id = wx.NewId()
226        slicerpop.Append(id, '&Change scale')
227        wx.EVT_MENU(self, id, self._onProperties)
228       
229        id = wx.NewId()
230        slicerpop.Append(id, '&Reset Graph')
[d468daa]231        wx.EVT_MENU(self, id, self.onResetGraph) 
232       
233        slicerpop.AppendSeparator() 
234        id = wx.NewId()
235        slicerpop.Append(id,'&Printer setup', 'Set image size')
236        wx.EVT_MENU(self, id, self.onPrinterSetup)
237       
238        id = wx.NewId()
239        slicerpop.Append(id,'&Printer Preview', 'Set image size')
240        wx.EVT_MENU(self, id, self.onPrinterPreview)
241   
242        id = wx.NewId()
243        slicerpop.Append(id,'&Print image', 'Print image ')
244        wx.EVT_MENU(self, id, self.onPrint)     
[1bf33c1]245
246        pos = event.GetPosition()
247        pos = self.ScreenToClient(pos)
248        self.PopupMenu(slicerpop, pos)
249   
250   
251    def _on_add_errors(self, evt):
252        """
253            Compute reasonable errors for a data set without
254            errors and transorm the plottable to a Data1D
255        """
256        import math
257        import numpy
258        import time
259       
260        if not self.graph.selected_plottable == None:
261            length = len(self.plots[self.graph.selected_plottable].x)
262            dy = numpy.zeros(length)
263            for i in range(length):
264                dy[i] = math.sqrt(self.plots[self.graph.selected_plottable].y[i])
265               
266            new_plot = Data1D(self.plots[self.graph.selected_plottable].x,
267                              self.plots[self.graph.selected_plottable].y,
268                              dy=dy)
269            new_plot.interactive = True
270            new_plot.name = self.plots[self.graph.selected_plottable].name
271            if hasattr(self.plots[self.graph.selected_plottable], "group_id"):
272                new_plot.group_id = self.plots[self.graph.selected_plottable].group_id
[d1dd9d4]273                new_plot.id = self.plots[self.graph.selected_plottable].id
[1bf33c1]274            else:
275                new_plot.group_id = str(time.time())
[d1dd9d4]276                new_plot.id = str(time.time())
[1bf33c1]277           
278            label, unit = self.plots[self.graph.selected_plottable].get_xaxis()
279            new_plot.xaxis(label, unit)
280            label, unit = self.plots[self.graph.selected_plottable].get_yaxis()
281            new_plot.yaxis(label, unit)
[ffd23b5]282            #print "panel scale ",self.xLabel, self.yLabel
[1bf33c1]283            self.graph.delete(self.plots[self.graph.selected_plottable])
284           
285            self.graph.add(new_plot)
[ffd23b5]286            # transforming the view of the new data into the same of the previous data
287            self._onEVT_FUNC_PROPERTY()
288            #print "cyllinder", self.plots[self.graph.selected_plottable].x,self.plots[self.graph.selected_plottable].view.x, new_plot.x, new_plot.view.x
[1bf33c1]289            self.plots[self.graph.selected_plottable]=new_plot
290           
291            self.graph.render(self)
292            self.subplot.figure.canvas.draw_idle()   
293   
294    def _onSave(self, evt):
295        """
296            Save a data set to a text file
297            @param evt: Menu event
298        """
299        import os
300        id = str(evt.GetId())
301        if id in self.action_ids:         
302           
303            path = None
304            dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "*.txt", wx.SAVE)
305            if dlg.ShowModal() == wx.ID_OK:
306                path = dlg.GetPath()
307                mypath = os.path.basename(path)
[d468daa]308                #print path
[1bf33c1]309            dlg.Destroy()
310           
311            if not path == None:
312                out = open(path, 'w')
313                has_errors = True
314                if self.action_ids[id].dy==None or self.action_ids[id].dy==[]:
315                    has_errors = False
316                   
317                # Sanity check
318                if has_errors:
319                    try:
320                        if len(self.action_ids[id].y) != len(self.action_ids[id].dy):
[d468daa]321                            #print "Y and dY have different lengths"
[1bf33c1]322                            has_errors = False
323                    except:
324                        has_errors = False
325               
326                if has_errors:
327                    out.write("<X>   <Y>   <dY>\n")
328                else:
329                    out.write("<X>   <Y>\n")
330                   
331                for i in range(len(self.action_ids[id].x)):
332                    if has_errors:
333                        out.write("%g  %g  %g\n" % (self.action_ids[id].x[i], 
334                                                    self.action_ids[id].y[i],
335                                                    self.action_ids[id].dy[i]))
336                    else:
337                        out.write("%g  %g\n" % (self.action_ids[id].x[i], 
338                                                self.action_ids[id].y[i]))
339                       
340                out.close()
341   
[d468daa]342 
343
[1bf33c1]344    def _onToggleScale(self, event):
345        if self.get_yscale() == 'log':
346            self.set_yscale('linear')
347        else:
348            self.set_yscale('log')
349        self.subplot.figure.canvas.draw_idle()   
350       
Note: See TracBrowser for help on using the repository browser.