source: sasview/guiframe/local_perspectives/plotting/Plotter1D.py @ 22210ef

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

print stament removed

  • Property mode set to 100644
File size: 12.8 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
14import pylab
15
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
20from sans.guicomm.events import StatusEvent ,NewPlotEvent,SlicerEvent
21from sans.guiframe.utils import PanelMenu
22
23from binder import BindArtist
24
25
26DEFAULT_QMAX = 0.05
27DEFAULT_QSTEP = 0.001
28DEFAULT_BEAM = 0.005
29BIN_WIDTH =1
30
31
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        """
84       
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__:
100                #overwrite a plottable using the same name
101                self.graph.delete(self.plots[event.plot.name])
102            else:
103                # plottable is already draw on the panel
104                is_new = False
105       
106           
107           
108        if is_new:
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           
114            self.plots[event.plot.name] = event.plot
115            self.graph.add(self.plots[event.plot.name])
116        else:
117            #replot the graph
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"]:
128       
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
135       
136        self._onEVT_FUNC_PROPERTY()
137   
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:
154            #print self.graph.selected_plottable
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)
187           
188            # Option to hide
189            #TODO: implement functionality to hide a plottable (legend click)
190           
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       
197        slicerpop.AppendSeparator()
198        item_list = self.parent.get_context_menu(self.graph)
199        #print "item_list",item_list
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:
207                        pass
208                        #print sys.exc_value
209                        #print RuntimeError, "View1DPanel.onContextMenu: bad menu item"
210       
211       
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')
216                #print "panel scale before  ",self.xLabel, self.yLabel
217                #print "cyllinder before adding error", self.plots[self.graph.selected_plottable].x
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               
224        slicerpop.AppendSeparator()
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')
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)     
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
273                new_plot.id = self.plots[self.graph.selected_plottable].id
274            else:
275                new_plot.group_id = str(time.time())
276                new_plot.id = str(time.time())
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)
282            #print "panel scale ",self.xLabel, self.yLabel
283            self.graph.delete(self.plots[self.graph.selected_plottable])
284           
285            self.graph.add(new_plot)
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
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)
308                #print path
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):
321                            #print "Y and dY have different lengths"
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   
342 
343
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.