source: sasview/guitools/PlotPanel.py @ 38fc601

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

more changes on the dragging .the user can see the picture move more slowly

  • Property mode set to 100644
File size: 30.3 KB
Line 
1import wx.lib.newevent
2import matplotlib
3matplotlib.interactive(False)
4#Use the WxAgg back end. The Wx one takes too long to render
5matplotlib.use('WXAgg')
6from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
7from matplotlib.figure import Figure
8import os
9import fittings
10import transform
11from canvas import FigureCanvas
12from matplotlib.widgets import RectangleSelector
13from pylab import  gca, gcf
14from plottables import Theory1D
15
16#from matplotlib.backend_bases import MouseEvent
17#from plottables import Data1D
18#TODO: make the plottables interactive
19
20DEBUG = False
21print "hello"
22
23from plottables import Graph
24#(FuncFitEvent, EVT_FUNC_FIT) = wx.lib.newevent.NewEvent()
25import math,pylab,re
26
27def show_tree(obj,d=0):
28    """Handy function for displaying a tree of graph objects"""
29    print "%s%s" % ("-"*d,obj.__class__.__name__)
30    if 'get_children' in dir(obj):
31        for a in obj.get_children(): show_tree(a,d+1)
32     
33from unitConverter import UnitConvertion as convertUnit   
34def _convertUnit(pow,unit):
35    """
36        Displays the unit with the proper convertion
37        @param pow: the user set the power of the unit
38        @param unit: the unit of the data
39    """ 
40    return unit
41    toks=re.match("^", unit)
42    if not toks==None:
43        unitValue= re.split("{",unit)
44        unitPower= re.split("}",unitValue[1])
45        power= int(unitPower[0])*pow
46        word= unitValue[0]+"{"+str(power)+"}"
47        if power==1:
48            tempUnit=re.split("\^",unitValue[0])
49            unit=tempUnit[0]
50        else:
51            unit = word
52    #print"this is unit",unit
53    return unit
54def _rescale(lo,hi,step,pt=None,bal=None,scale='linear'):
55        """
56        Rescale (lo,hi) by step, returning the new (lo,hi)
57        The scaling is centered on pt, with positive values of step
58        driving lo/hi away from pt and negative values pulling them in.
59        If bal is given instead of point, it is already in [0,1] coordinates.
60   
61        This is a helper function for step-based zooming.
62        """
63        # Convert values into the correct scale for a linear transformation
64        # TODO: use proper scale transformers
65        loprev = lo
66        hiprev = hi
67        ptprev = pt
68        if scale=='log':
69            assert lo >0
70            if lo > 0 :
71                lo = math.log10(lo)
72            if hi > 0 :
73                hi = math.log10(hi)
74            if pt is not None: pt = math.log10(pt)
75       
76        # Compute delta from axis range * %, or 1-% if persent is negative
77        if step > 0:
78            delta = float(hi-lo)*step/100
79        else:
80            delta = float(hi-lo)*step/(100-step)
81   
82        # Add scale factor proportionally to the lo and hi values, preserving the
83        # point under the mouse
84        if bal is None:
85            bal = float(pt-lo)/(hi-lo)
86        lo = lo - bal*delta
87        hi = hi + (1-bal)*delta
88   
89        # Convert transformed values back to the original scale
90        if scale=='log':
91            if (lo <= -250) or (hi >= 250):
92                lo=loprev
93                hi=hiprev
94                print "Not possible to scale"
95           
96            else:
97                lo,hi = math.pow(10.,lo),math.pow(10.,hi)
98                #assert lo >0,"lo = %g"%lo
99                print "possible to scale"
100           
101            print "these are low and high",lo,hi
102
103        return (lo,hi)
104
105
106class PlotPanel(wx.Panel):
107    """
108    The PlotPanel has a Figure and a Canvas. OnSize events simply set a
109    flag, and the actually redrawing of the
110    figure is triggered by an Idle event.
111    """
112    def __init__(self, parent, id = -1, color = None,\
113        dpi = None, **kwargs):
114        wx.Panel.__init__(self, parent, id = id, **kwargs)
115        self.parent = parent
116        self.figure = Figure(None, dpi)
117        #self.figure = pylab.Figure(None, dpi)
118        #self.canvas = NoRepaintCanvas(self, -1, self.figure)
119        self.canvas = FigureCanvas(self, -1, self.figure)
120        self.SetColor(color)
121        #self.Bind(wx.EVT_IDLE, self._onIdle)
122        #self.Bind(wx.EVT_SIZE, self._onSize)
123        self._resizeflag = True
124        self._SetSize()
125        self.subplot = self.figure.add_subplot(111)
126        self.figure.subplots_adjust(left=.2, bottom=.2)
127        self.yscale = 'linear'
128        self.xscale = 'linear'
129        sizer = wx.BoxSizer(wx.VERTICAL)
130        sizer.Add(self.canvas,1,wx.EXPAND)
131        self.SetSizer(sizer)
132       
133        # Graph object to manage the plottables
134        self.graph = Graph()
135        #self.Bind(EVT_FUNC_FIT, self.onFitRange)
136        self.Bind(wx.EVT_CONTEXT_MENU, self.onContextMenu)
137       
138        #self.Bind(EVT_PROPERTY, self._onEVT_FUNC_PROPERTY)
139        # Define some constants
140        self.colorlist = ['b','g','r','c','m','y']
141        self.symbollist = ['o','x','^','v','<','>','+','s','d','D','h','H','p']
142        #User scale
143        self.xLabel ="x"
144        self.yLabel ="y"
145        self.viewModel ="--"
146        # keep track if the previous transformation of x and y in Property dialog
147        self.prevXtrans ="x"
148        self.prevYtrans ="y"
149        self.canvas.mpl_connect('scroll_event',self.onWheel)
150        #taking care of dragging
151        self.canvas.mpl_connect('motion_notify_event',self.onMouseMotion)
152        self.canvas.mpl_connect('button_press_event',self.onLeftDown)
153        self.canvas.mpl_connect('button_release_event',self.onLeftUp)
154       
155       
156        self.leftdown=False
157        self.leftup=False
158        self.mousemotion=False
159       
160        #self.canvas.Bind(wx.EVT_MOUSE_EVENTS,self.onTest)
161        self.axes = [self.subplot]
162         # new data for the fit
163        self.fit_result = Theory1D(x=[], y=[], dy=None)
164        #self.fit_result = Data1D(x=[], y=[],dx=None, dy=None)
165        self.fit_result.name = "Fit"
166        # For fit Dialog initial display
167        self.xmin=0.0
168        self.xmax=0.0
169        self.xminView=0.0
170        self.xmaxView=0.0
171        self.Avalue=None
172        self.Bvalue=None
173        self.ErrAvalue=None
174        self.ErrBvalue=None
175        self.Chivalue=None
176        self.begDrag=False
177        #self.begDragI=False
178        self.xInit=None
179        self.yInit=None
180        self.xFinal=None
181        self.yFinal=None
182 
183    def onLeftDown(self,event): 
184        """ left button down and ready to drag"""
185        self.leftdown=True
186        #self.mousemotion=False
187        ax = event.inaxes
188        if ax !=None:
189            x,y = event.x,event.y
190            #print "these are x %f and y %f"%(x,y)
191            self.xInit,self.yInit=ax.transAxes.inverse_xy_tup((x,y))
192            #print "this is xInit %f this is yInit %f"%(self.xInit, self.yInit)
193    def onLeftUp(self,event): 
194        """ Dragging is done """
195        self.leftdown=False
196        self.mousemotion=False 
197        self.leftup=True
198        """
199        if self.mousemotion==True:
200            ax = event.inaxes
201            if ax !=None:
202                x,y = event.x,event.y
203                self.xFinal,self.yFinal=ax.transAxes.inverse_xy_tup((x,y))
204               
205                xdelta = self.xFinal -self.xInit
206                ydelta = self.yFinal -self.yInit
207               
208                if self.xscale=='log':
209                    xdelta = math.log10(self.xFinal) -math.log10(self.xInit)
210                if self.yscale=='log':
211                    ydelta = math.log10(self.yFinal) -math.log10(self.yInit)
212                self.dragHelper(xdelta,ydelta)
213                print "this is xInit %f this is xFinal %f \n"%(self.xInit, self.xFinal)
214                print "this is yInit %f this is yFinal %f \n"%(self.yInit, self.yFinal)
215                print "this is xdelta %f and ydelta %f \n"%(xdelta,ydelta)
216            else:
217                self.dragHelper(0,0)
218               
219               """
220    def onMouseMotion(self,event): 
221        self.mousemotion=True 
222        if self.leftdown==True and self.mousemotion==True:
223           
224            ax = event.inaxes
225            if ax !=None:
226                x,y = event.x,event.y
227                self.xFinal,self.yFinal=ax.transAxes.inverse_xy_tup((x,y))
228               
229                xdelta = self.xFinal -self.xInit
230                ydelta = self.yFinal -self.yInit
231               
232                if self.xscale=='log':
233                    xdelta = math.log10(self.xFinal) -math.log10(self.xInit)
234                if self.yscale=='log':
235                    ydelta = math.log10(self.yFinal) -math.log10(self.yInit)
236                self.dragHelper(xdelta,ydelta)
237                print "this is xInit %f this is xFinal %f \n"%(self.xInit, self.xFinal)
238                print "this is yInit %f this is yFinal %f \n"%(self.yInit, self.yFinal)
239                print "this is xdelta %f and ydelta %f \n"%(xdelta,ydelta)
240            else:
241                self.dragHelper(0,0)
242    def dragHelper(self,xdelta,ydelta):
243        """ dragging occurs here"""
244       
245        # Event occurred inside a plotting area
246        for ax in self.axes:
247            lo,hi= ax.get_xlim()
248            #print "x lo %f and x hi %f"%(lo,hi)
249            newlo,newhi= lo- xdelta, hi- xdelta
250            if self.xscale=='log':
251                if lo > 0:
252                    newlo= math.log10(lo)-xdelta
253                if hi > 0:
254                    newhi= math.log10(hi)-xdelta
255            if self.xscale=='log':
256                ax.set_xlim(math.pow(10,newlo),math.pow(10,newhi))
257            else:
258                ax.set_xlim(newlo,newhi)
259            #print "new lo %f and new hi %f"%(newlo,newhi)
260           
261            lo,hi= ax.get_ylim()
262            #print "y lo %f and y hi %f"%(lo,hi)
263            newlo,newhi= lo- ydelta, hi- ydelta
264            if self.yscale=='log':
265                if lo > 0:
266                    newlo= math.log10(lo)-ydelta
267                if hi > 0:
268                    newhi= math.log10(hi)-ydelta
269                #print "new lo %f and new hi %f"%(newlo,newhi)
270            if  self.yscale=='log':
271                ax.set_ylim(math.pow(10,newlo),math.pow(10,newhi))
272            else:
273                ax.set_ylim(newlo,newhi)
274        self.canvas.draw_idle()
275       
276       
277   
278    def resetFitView(self):
279        """
280             For fit Dialog initial display
281        """
282        self.xmin=0.0
283        self.xmax=0.0
284        self.xminView=0.0
285        self.xmaxView=0.0
286        self.Avalue=None
287        self.Bvalue=None
288        self.ErrAvalue=None
289        self.ErrBvalue=None
290        self.Chivalue=None
291   
292    def onWheel(self, event):
293        """
294            Process mouse wheel as zoom events
295            @param event: Wheel event
296        """
297        ax = event.inaxes
298        step = event.step
299
300        if ax != None:
301            # Event occurred inside a plotting area
302            lo,hi = ax.get_xlim()
303            lo,hi = _rescale(lo,hi,step,pt=event.xdata,scale=ax.get_xscale())
304            if not self.xscale=='log' or lo>0:
305                ax.set_xlim((lo,hi))
306
307            lo,hi = ax.get_ylim()
308            lo,hi = _rescale(lo,hi,step,pt=event.ydata,scale=ax.get_yscale())
309            if not self.yscale=='log' or lo>0:
310                ax.set_ylim((lo,hi))
311        else:
312             # Check if zoom happens in the axes
313            xdata,ydata = None,None
314            x,y = event.x,event.y
315           
316            for ax in self.axes:
317                insidex,_ = ax.xaxis.contains(event)
318                if insidex:
319                    xdata,_ = ax.transAxes.inverse_xy_tup((x,y))
320                insidey,_ = ax.yaxis.contains(event)
321                if insidey:
322                    _,ydata = ax.transAxes.inverse_xy_tup((x,y))
323            if xdata is not None:
324                lo,hi = ax.get_xlim()
325                lo,hi = _rescale(lo,hi,step,bal=xdata,scale=ax.get_xscale())
326                if not self.xscale=='log' or lo>0:
327                    ax.set_xlim((lo,hi))
328            if ydata is not None:
329                lo,hi = ax.get_ylim()
330                lo,hi = _rescale(lo,hi,step,bal=ydata,scale=ax.get_yscale())
331                if not self.yscale=='log' or lo>0:
332                    ax.set_ylim((lo,hi))
333               
334        self.canvas.draw_idle()
335
336
337    def returnTrans(self):
338        """
339            Return values and labels used by Fit Dialog
340        """
341        return self.xLabel,self.yLabel, self.Avalue, self.Bvalue,\
342                self.ErrAvalue,self.ErrBvalue,self.Chivalue
343   
344    def setTrans(self,xtrans,ytrans): 
345        """
346            @param xtrans: set x transformation on Property dialog
347            @param ytrans: set y transformation on Property dialog
348        """
349        self.prevXtrans =xtrans
350        self.prevYtrans =ytrans
351   
352    def onFitting(self, event): 
353        """
354            when clicking on linear Fit on context menu , display Fitting Dialog
355        """
356        list =[]
357        list = self.graph.returnPlottable()
358        from fitDialog import LinearFit
359       
360        if len(list.keys())>0:
361            first_item = list.keys()[0]
362            dlg = LinearFit( None, first_item, self.onFitDisplay,self.returnTrans, -1, 'Linear Fit')
363           
364            if (self.xmin !=0.0 )and ( self.xmax !=0.0)\
365                and(self.xminView !=0.0 )and ( self.xmaxView !=0.0):
366                dlg.setFitRange(self.xminView,self.xmaxView,self.xmin,self.xmax)
367            dlg.ShowModal() 
368
369    def linear_plottable_fit(self, plot): 
370        """
371            when clicking on linear Fit on context menu , display Fitting Dialog
372        """
373        from fitDialog import LinearFit
374       
375        dlg = LinearFit( None, plot, self.onFitDisplay,self.returnTrans, -1, 'Linear Fit')
376       
377        if (self.xmin !=0.0 )and ( self.xmax !=0.0)\
378            and(self.xminView !=0.0 )and ( self.xmaxView !=0.0):
379            dlg.setFitRange(self.xminView,self.xmaxView,self.xmin,self.xmax)
380        dlg.ShowModal() 
381
382    def _onProperties(self, event):
383        """
384            when clicking on Properties on context menu ,The Property dialog is displayed
385            The user selects a transformation for x or y value and a new plot is displayed
386        """
387        list =[]
388        list = self.graph.returnPlottable()
389        if len(list.keys())>0:
390            first_item = list.keys()[0]
391            if first_item.x !=[]:
392                from PropertyDialog import Properties
393                dial = Properties(self, -1, 'Properties')
394                dial.setValues( self.prevXtrans, self.prevYtrans,self.viewModel )
395                if dial.ShowModal() == wx.ID_OK:
396                    self.xLabel, self.yLabel,self.viewModel = dial.getValues()
397                    if self.viewModel =="Guinier lny vs x^(2)":
398                        self.xLabel="x^(2)"
399                        self.yLabel="ln(y)"
400                        self.viewModel = "--"
401                        dial.setValues( self.xLabel, self.yLabel,self.viewModel )
402                    self._onEVT_FUNC_PROPERTY()
403                dial.Destroy()
404           
405 
406    def set_yscale(self, scale='linear'):
407        """
408            Set the scale on Y-axis
409            @param scale: the scale of y-axis
410        """
411        self.subplot.set_yscale(scale)
412        self.yscale = scale
413       
414    def get_yscale(self):
415        """
416             @return: Y-axis scale
417        """
418        return self.yscale
419   
420    def set_xscale(self, scale='linear'):
421        """
422            Set the scale on x-axis
423            @param scale: the scale of x-axis
424        """
425        self.subplot.set_xscale(scale)
426        self.xscale = scale
427       
428    def get_xscale(self):
429        """
430             @return: x-axis scale
431        """
432        return self.xscale
433
434    def SetColor(self, rgbtuple):
435        """Set figure and canvas colours to be the same"""
436        if not rgbtuple:
437            rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
438        col = [c/255.0 for c in rgbtuple]
439        self.figure.set_facecolor(col)
440        self.figure.set_edgecolor(col)
441        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))
442
443    def _onSize(self, event):
444        self._resizeflag = True
445
446    def _onIdle(self, evt):
447        if self._resizeflag:
448            self._resizeflag = False
449            self._SetSize()
450            self.draw()
451
452    def _SetSize(self, pixels = None):
453        """
454        This method can be called to force the Plot to be a desired size, which defaults to
455        the ClientSize of the panel
456        """
457        if not pixels:
458            pixels = self.GetClientSize()
459        self.canvas.SetSize(pixels)
460        self.figure.set_size_inches(pixels[0]/self.figure.get_dpi(),
461        pixels[1]/self.figure.get_dpi())
462
463    def draw(self):
464        """Where the actual drawing happens"""
465        self.figure.canvas.draw_idle()
466       
467       
468    def onSaveImage(self, evt):
469        #figure.savefig
470        #print "Save image not implemented"
471        path = None
472        dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "*.png", wx.SAVE)
473        if dlg.ShowModal() == wx.ID_OK:
474            path = dlg.GetPath()
475            mypath = os.path.basename(path)
476            print path
477        dlg.Destroy()
478        if not path == None:
479            self.subplot.figure.savefig(path,dpi=300, facecolor='w', edgecolor='w',
480                                        orentation='portrait', papertype=None, format='png')
481       
482    def onContextMenu(self, event):
483        """
484            Default context menu for a plot panel
485        """
486        # Slicer plot popup menu
487        id = wx.NewId()
488        slicerpop = wx.Menu()
489        slicerpop.Append(id,'&Save image', 'Save image as PNG')
490        wx.EVT_MENU(self, id, self.onSaveImage)
491       
492        #id = wx.NewId()
493        #slicerpop.Append(id, '&Load 1D data file')
494        #wx.EVT_MENU(self, id, self._onLoad1DData)
495       
496        id = wx.NewId()
497        slicerpop.AppendSeparator()
498        slicerpop.Append(id, '&Properties')
499        wx.EVT_MENU(self, id, self._onProperties)
500       
501        id = wx.NewId()
502        slicerpop.AppendSeparator()
503        slicerpop.Append(id, '&Linear Fit')
504        wx.EVT_MENU(self, id, self.onFitting)
505       
506        id = wx.NewId()
507        slicerpop.AppendSeparator()
508        slicerpop.Append(id, '&Reset Graph')
509        wx.EVT_MENU(self, id, self.onResetGraph)
510       
511        pos = event.GetPosition()
512        pos = self.ScreenToClient(pos)
513        self.PopupMenu(slicerpop, pos)
514   
515    ## The following is plottable functionality
516
517
518    def properties(self,prop):
519        """Set some properties of the graph.
520       
521        The set of properties is not yet determined.
522        """
523        # The particulars of how they are stored and manipulated (e.g., do
524        # we want an inventory internally) is not settled.  I've used a
525        # property dictionary for now.
526        #
527        # How these properties interact with a user defined style file is
528        # even less clear.
529
530        # Properties defined by plot
531        self.subplot.set_xlabel(r"$%s$" % prop["xlabel"])
532        self.subplot.set_ylabel(r"$%s$" % prop["ylabel"])
533        self.subplot.set_title(prop["title"])
534
535        # Properties defined by user
536        #self.axes.grid(True)
537
538    def clear(self):
539        """Reset the plot"""
540       
541        # TODO: Redraw is brutal.  Render to a backing store and swap in
542        # TODO: rather than redrawing on the fly.
543        self.subplot.clear()
544        self.subplot.hold(True)
545   
546    def render(self):
547        """Commit the plot after all objects are drawn"""
548        # TODO: this is when the backing store should be swapped in.
549        from matplotlib.font_manager import FontProperties
550        self.subplot.legend(prop=FontProperties(size=10))
551        #self.subplot.legend()
552        pass
553
554    def xaxis(self,label,units):
555        """xaxis label and units.
556       
557        Axis labels know about units.
558       
559        We need to do this so that we can detect when axes are not
560        commesurate.  Currently this is ignored other than for formatting
561        purposes.
562        """
563        if units != "": label = label + " (" + units + ")"
564        self.subplot.set_xlabel(label)
565        pass
566   
567    def yaxis(self,label,units):
568        """yaxis label and units."""
569        if units != "": label = label + " (" + units + ")"
570        self.subplot.set_ylabel(label)
571        pass
572
573    def _connect_to_xlim(self,callback):
574        """Bind the xlim change notification to the callback"""
575        def process_xlim(axes):
576            lo,hi = subplot.get_xlim()
577            callback(lo,hi)
578        self.subplot.callbacks.connect('xlim_changed',process_xlim)
579   
580    #def connect(self,trigger,callback):
581    #    print "PlotPanel.connect???"
582    #    if trigger == 'xlim': self._connect_to_xlim(callback)
583
584    def points(self,x,y,dx=None,dy=None,color=0,symbol=0,label=None):
585        """Draw markers with error bars"""
586        self.subplot.set_yscale('linear')
587        self.subplot.set_xscale('linear')
588       
589        # Convert tuple (lo,hi) to array [(x-lo),(hi-x)]
590        if dx != None and type(dx) == type(()):
591            dx = nx.vstack((x-dx[0],dx[1]-x)).transpose()
592        if dy != None and type(dy) == type(()):
593            dy = nx.vstack((y-dy[0],dy[1]-y)).transpose()
594
595        if dx==None and dy==None:
596            h = self.subplot.plot(x,y,color=self._color(color),
597                                   marker=self._symbol(symbol),linestyle='',label=label)
598        else:
599            col = self._color(color)
600            self.subplot.errorbar(x, y, yerr=dy, xerr=None,
601             ecolor=col, capsize=2,linestyle='', barsabove=False,
602             mec=col, mfc=col,
603             marker=self._symbol(symbol),
604             lolims=False, uplims=False,
605             xlolims=False, xuplims=False,label=label)
606           
607        self.subplot.set_yscale(self.yscale)
608        self.subplot.set_xscale(self.xscale)
609
610    def curve(self,x,y,dy=None,color=0,symbol=0,label=None):
611        """Draw a line on a graph, possibly with confidence intervals."""
612        c = self._color(color)
613        self.subplot.set_yscale('linear')
614        self.subplot.set_xscale('linear')
615       
616        hlist = self.subplot.plot(x,y,color=c,marker='',linestyle='-',label=label)
617       
618        self.subplot.set_yscale(self.yscale)
619        self.subplot.set_xscale(self.xscale)
620
621    def _color(self,c):
622        """Return a particular colour"""
623        return self.colorlist[c%len(self.colorlist)]
624
625    def _symbol(self,s):
626        """Return a particular symbol"""
627        return self.symbollist[s%len(self.symbollist)]
628   
629    def _replot(self):
630        """
631            Rescale the plottables according to the latest
632            user selection and update the plot
633        """
634        self.graph.reset_scale()
635        self._onEVT_FUNC_PROPERTY(remove_fit=False)
636       
637        #TODO: Why do we have to have the following line?
638        self.fit_result.reset_view()
639       
640        self.graph.render(self)
641        self.subplot.figure.canvas.draw_idle()
642   
643    def _onEVT_FUNC_PROPERTY(self, remove_fit=True):
644        """
645             Receive the x and y transformation from myDialog,Transforms x and y in View
646              and set the scale   
647        """ 
648        list =[]
649        list = self.graph.returnPlottable()
650       
651        if remove_fit:
652            self.fit_result.x =[] 
653            self.fit_result.y =[] 
654            self.fit_result.dx=None
655            self.fit_result.dy=None
656            self.graph.delete(self.fit_result)
657       
658        for item in list:
659            item.setLabel(self.xLabel,self.yLabel)
660            if ( self.xLabel=="x" ):
661                item.transformX(transform.toX,transform.errToX)
662                self.set_xscale("linear")
663                name, units = item.get_xaxis()
664                self.graph.xaxis("%s" % name,  "%s" % units)
665               
666               
667            if ( self.xLabel=="x^(2)" ):
668                item.transformX(transform.toX2,transform.errToX2)
669                self.set_xscale('linear')
670                name, units = item.get_xaxis()
671                units=convertUnit(2,units) 
672                self.graph.xaxis("%s^{2}" % name,  "%s" % units)
673               
674               
675            if (self.xLabel=="log10(x)" ):
676                item.transformX(transform.toX,transform.errToX)
677                self.set_xscale("log")
678                name, units = item.get_xaxis() 
679                self.graph.xaxis("\log_{10}\ \  (%s)" % name,  "%s" % units)
680               
681               
682            if ( self.yLabel=="ln(y)" ):
683                item.transformY(transform.toLogX,transform.errToLogX)
684                self.set_yscale("linear")
685                name, units = item.get_yaxis()
686                self.graph.yaxis("log\ \ %s" % name,  "%s" % units)
687               
688               
689            if ( self.yLabel=="y" ):
690                item.transformY(transform.toX,transform.errToX)
691                self.set_yscale("linear")
692                name, units = item.get_yaxis()
693                self.graph.yaxis("%s" % name,  "%s" % units)
694               
695               
696            if ( self.yLabel=="log10(y)" ): 
697                item.transformY(transform.toX,transform.errToX)
698                self.set_yscale("log") 
699                name, units = item.get_yaxis()
700                self.graph.yaxis("\log_{10}\ \ (%s)" % name,  "%s" % units)
701               
702               
703            if ( self.yLabel=="y^(2)" ):
704                item.transformY( transform.toX2,transform.errToX2 )   
705                self.set_yscale("linear")
706                name, units = item.get_yaxis()
707                units=convertUnit(2,units) 
708                self.graph.yaxis("%s^{2}" % name,  "%s" % units)
709               
710               
711            if ( self.yLabel =="1/y"):
712                item.transformY(transform.toOneOverX,transform.errOneOverX )
713                self.set_yscale("linear")
714                name, units = item.get_yaxis()
715                units=convertUnit(-1,units)
716                self.graph.yaxis("1/%s" % name,  "%s" % units)
717               
718            if ( self.yLabel =="1/sqrt(y)" ):
719                item.transformY(transform.toOneOverSqrtX,transform.errOneOverSqrtX )
720                self.set_yscale("linear")
721                name, units = item.get_yaxis()
722                units=convertUnit(-0.5,units)
723                self.graph.yaxis("1/\sqrt{%s}" %name,  "%s" % units)
724               
725            if ( self.yLabel =="ln(y*x)"):
726                item.transformY( transform.toLogXY,transform.errToLogXY)
727                self.set_yscale("linear")
728                yname, yunits = item.get_yaxis()
729                xname, xunits = item.get_xaxis()
730                self.graph.yaxis("log\ (%s \ \ %s)" % (yname,xname),  "%s%s" % (yunits,xunits))
731               
732               
733            if ( self.yLabel =="ln(y*x^(2))"):
734                item.transformY( transform.toLogYX2,transform.errToLogYX2)
735                self.set_yscale("linear")
736                yname, yunits = item.get_yaxis()
737                xname, xunits = item.get_xaxis() 
738                xunits = convertUnit(2,xunits) 
739                self.graph.yaxis("Log (%s \ \ %s^{2})" % (yname,xname),  "%s%s" % (yunits,xunits))
740               
741           
742            if ( self.yLabel =="ln(y*x^(4))"):
743                item.transformY(transform.toLogYX4,transform.errToLogYX4)
744                self.set_yscale("linear")
745                yname, yunits = item.get_yaxis()
746                xname, xunits = item.get_xaxis()
747                xunits = convertUnit(4,xunits) 
748                self.graph.yaxis("Log (%s \ \ %s^{4})" % (yname,xname),  "%s%s" % (yunits,xunits))
749               
750            if ( self.viewModel == "Guinier lny vs x^(2)"):
751               
752                item.transformX(transform.toX2,transform.errToX2)
753                self.set_xscale('linear')
754                name, units = item.get_xaxis()
755                units = convertUnit(2,units) 
756                self.graph.xaxis("%s^{2}" % name,  "%s" % units)
757               
758               
759                item.transformY(transform.toLogX,transform.errToLogX )
760                self.set_yscale("linear")
761                name, units = item.get_yaxis()
762                self.graph.yaxis("$Log %s$" % name,  "%s" % units)
763               
764               
765            item.transformView()
766           
767         
768        self.resetFitView()   
769        self.prevXtrans = self.xLabel
770        self.prevYtrans = self.yLabel 
771        self.graph.render(self)
772        self.subplot.figure.canvas.draw_idle()
773       
774       
775   
776    def onFitDisplay(self, tempx,tempy,xminView,xmaxView,xmin,xmax,func):
777        """
778            Add a new plottable into the graph .In this case this plottable will be used
779            to fit some data
780            @param tempx: The x data of fit line
781            @param tempy: The y data of fit line
782            @param xminView: the lower bound of fitting range
783            @param xminView: the upper bound of  fitting range
784            @param xmin: the lowest value of data to fit to the line
785            @param xmax: the highest value of data to fit to the line
786        """
787        # Saving value to redisplay in Fit Dialog when it is opened again
788        self.Avalue,self.Bvalue,self.ErrAvalue,self.ErrBvalue,self.Chivalue=func
789        self.xminView=xminView
790        self.xmaxView=xmaxView
791        self.xmin= xmin
792        self.xmax= xmax
793        #In case need to change the range of data plotted
794        list =[]
795        list = self.graph.returnPlottable()
796        for item in list:
797            #item.onFitRange(xminView,xmaxView)
798            item.onFitRange(None,None)
799       
800        # Create new data plottable with result
801        self.fit_result.x =[] 
802        self.fit_result.y =[]
803        self.fit_result.x =tempx 
804        self.fit_result.y =tempy     
805        self.fit_result.dx=None
806        self.fit_result.dy=None
807        #Load the view with the new values
808        self.fit_result.reset_view()
809        # Add the new plottable to the graph
810        self.graph.add(self.fit_result) 
811        self.graph.render(self)
812        self.subplot.figure.canvas.draw_idle()
813       
814   
815    def onResetGraph(self,event):
816        """
817            Reset the graph by plotting the full range of data
818        """
819        list =[]
820        list = self.graph.returnPlottable()
821        for item in list:
822            item.onReset()
823        self.graph.render(self)
824        self.subplot.figure.canvas.draw_idle()
825       
826class NoRepaintCanvas(FigureCanvasWxAgg):
827    """We subclass FigureCanvasWxAgg, overriding the _onPaint method, so that
828    the draw method is only called for the first two paint events. After that,
829    the canvas will only be redrawn when it is resized.
830    """
831    def __init__(self, *args, **kwargs):
832        FigureCanvasWxAgg.__init__(self, *args, **kwargs)
833        self._drawn = 0
834
835    def _onPaint(self, evt):
836        """
837        Called when wxPaintEvt is generated
838        """
839        if not self._isRealized:
840            self.realize()
841        if self._drawn < 2:
842            self.draw(repaint = False)
843            self._drawn += 1
844        self.gui_repaint(drawDC=wx.PaintDC(self))
845           
Note: See TracBrowser for help on using the repository browser.