source: sasview/guitools/PlotPanel.py @ b659551

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

plotpanel clean up

  • Property mode set to 100644
File size: 29.2 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        ax = event.inaxes
187        if ax !=None:
188            self.xInit,self.yInit=event.xdata,event.ydata
189           
190           
191    def onLeftUp(self,event): 
192        """ Dragging is done """
193        self.leftdown=False
194        self.mousemotion=False 
195        self.leftup=True
196     
197    def onMouseMotion(self,event): 
198        """
199            check if the left button is press and the mouse in moving.
200            computer delta for x and y coordinates and then calls draghelper
201            to perform the drag
202        """
203        self.mousemotion=True 
204        if self.leftdown==True and self.mousemotion==True:
205           
206            ax = event.inaxes
207            if ax !=None:#the dragging is perform inside the figure
208                self.xFinal,self.yFinal=event.xdata,event.ydata
209               
210                xdelta = self.xFinal -self.xInit
211                ydelta = self.yFinal -self.yInit
212               
213                if self.xscale=='log':
214                    xdelta = math.log10(self.xFinal) -math.log10(self.xInit)
215                if self.yscale=='log':
216                    ydelta = math.log10(self.yFinal) -math.log10(self.yInit)
217                self.dragHelper(xdelta,ydelta)
218             
219            else:# no dragging is perform elsewhere
220                self.dragHelper(0,0)
221               
222    def dragHelper(self,xdelta,ydelta):
223        """ dragging occurs here"""
224       
225        # Event occurred inside a plotting area
226        for ax in self.axes:
227            lo,hi= ax.get_xlim()
228            #print "x lo %f and x hi %f"%(lo,hi)
229            newlo,newhi= lo- xdelta, hi- xdelta
230            if self.xscale=='log':
231                if lo > 0:
232                    newlo= math.log10(lo)-xdelta
233                if hi > 0:
234                    newhi= math.log10(hi)-xdelta
235            if self.xscale=='log':
236                ax.set_xlim(math.pow(10,newlo),math.pow(10,newhi))
237            else:
238                ax.set_xlim(newlo,newhi)
239            #print "new lo %f and new hi %f"%(newlo,newhi)
240           
241            lo,hi= ax.get_ylim()
242            #print "y lo %f and y hi %f"%(lo,hi)
243            newlo,newhi= lo- ydelta, hi- ydelta
244            if self.yscale=='log':
245                if lo > 0:
246                    newlo= math.log10(lo)-ydelta
247                if hi > 0:
248                    newhi= math.log10(hi)-ydelta
249                #print "new lo %f and new hi %f"%(newlo,newhi)
250            if  self.yscale=='log':
251                ax.set_ylim(math.pow(10,newlo),math.pow(10,newhi))
252            else:
253                ax.set_ylim(newlo,newhi)
254        self.canvas.draw_idle()
255       
256       
257   
258    def resetFitView(self):
259        """
260             For fit Dialog initial display
261        """
262        self.xmin=0.0
263        self.xmax=0.0
264        self.xminView=0.0
265        self.xmaxView=0.0
266        self.Avalue=None
267        self.Bvalue=None
268        self.ErrAvalue=None
269        self.ErrBvalue=None
270        self.Chivalue=None
271   
272    def onWheel(self, event):
273        """
274            Process mouse wheel as zoom events
275            @param event: Wheel event
276        """
277        ax = event.inaxes
278        step = event.step
279
280        if ax != None:
281            # Event occurred inside a plotting area
282            lo,hi = ax.get_xlim()
283            lo,hi = _rescale(lo,hi,step,pt=event.xdata,scale=ax.get_xscale())
284            if not self.xscale=='log' or lo>0:
285                ax.set_xlim((lo,hi))
286
287            lo,hi = ax.get_ylim()
288            lo,hi = _rescale(lo,hi,step,pt=event.ydata,scale=ax.get_yscale())
289            if not self.yscale=='log' or lo>0:
290                ax.set_ylim((lo,hi))
291        else:
292             # Check if zoom happens in the axes
293            xdata,ydata = None,None
294            x,y = event.x,event.y
295           
296            for ax in self.axes:
297                insidex,_ = ax.xaxis.contains(event)
298                if insidex:
299                    xdata,_ = ax.transAxes.inverse_xy_tup((x,y))
300                insidey,_ = ax.yaxis.contains(event)
301                if insidey:
302                    _,ydata = ax.transAxes.inverse_xy_tup((x,y))
303            if xdata is not None:
304                lo,hi = ax.get_xlim()
305                lo,hi = _rescale(lo,hi,step,bal=xdata,scale=ax.get_xscale())
306                if not self.xscale=='log' or lo>0:
307                    ax.set_xlim((lo,hi))
308            if ydata is not None:
309                lo,hi = ax.get_ylim()
310                lo,hi = _rescale(lo,hi,step,bal=ydata,scale=ax.get_yscale())
311                if not self.yscale=='log' or lo>0:
312                    ax.set_ylim((lo,hi))
313               
314        self.canvas.draw_idle()
315
316
317    def returnTrans(self):
318        """
319            Return values and labels used by Fit Dialog
320        """
321        return self.xLabel,self.yLabel, self.Avalue, self.Bvalue,\
322                self.ErrAvalue,self.ErrBvalue,self.Chivalue
323   
324    def setTrans(self,xtrans,ytrans): 
325        """
326            @param xtrans: set x transformation on Property dialog
327            @param ytrans: set y transformation on Property dialog
328        """
329        self.prevXtrans =xtrans
330        self.prevYtrans =ytrans
331   
332    def onFitting(self, event): 
333        """
334            when clicking on linear Fit on context menu , display Fitting Dialog
335        """
336        list =[]
337        list = self.graph.returnPlottable()
338        from fitDialog import LinearFit
339       
340        if len(list.keys())>0:
341            first_item = list.keys()[0]
342            dlg = LinearFit( None, first_item, self.onFitDisplay,self.returnTrans, -1, 'Linear Fit')
343           
344            if (self.xmin !=0.0 )and ( self.xmax !=0.0)\
345                and(self.xminView !=0.0 )and ( self.xmaxView !=0.0):
346                dlg.setFitRange(self.xminView,self.xmaxView,self.xmin,self.xmax)
347            dlg.ShowModal() 
348
349    def linear_plottable_fit(self, plot): 
350        """
351            when clicking on linear Fit on context menu , display Fitting Dialog
352        """
353        from fitDialog import LinearFit
354       
355        dlg = LinearFit( None, plot, self.onFitDisplay,self.returnTrans, -1, 'Linear Fit')
356       
357        if (self.xmin !=0.0 )and ( self.xmax !=0.0)\
358            and(self.xminView !=0.0 )and ( self.xmaxView !=0.0):
359            dlg.setFitRange(self.xminView,self.xmaxView,self.xmin,self.xmax)
360        dlg.ShowModal() 
361
362    def _onProperties(self, event):
363        """
364            when clicking on Properties on context menu ,The Property dialog is displayed
365            The user selects a transformation for x or y value and a new plot is displayed
366        """
367        list =[]
368        list = self.graph.returnPlottable()
369        if len(list.keys())>0:
370            first_item = list.keys()[0]
371            if first_item.x !=[]:
372                from PropertyDialog import Properties
373                dial = Properties(self, -1, 'Properties')
374                dial.setValues( self.prevXtrans, self.prevYtrans,self.viewModel )
375                if dial.ShowModal() == wx.ID_OK:
376                    self.xLabel, self.yLabel,self.viewModel = dial.getValues()
377                    if self.viewModel =="Guinier lny vs x^(2)":
378                        self.xLabel="x^(2)"
379                        self.yLabel="ln(y)"
380                        self.viewModel = "--"
381                        dial.setValues( self.xLabel, self.yLabel,self.viewModel )
382                    self._onEVT_FUNC_PROPERTY()
383                dial.Destroy()
384           
385 
386    def set_yscale(self, scale='linear'):
387        """
388            Set the scale on Y-axis
389            @param scale: the scale of y-axis
390        """
391        self.subplot.set_yscale(scale)
392        self.yscale = scale
393       
394    def get_yscale(self):
395        """
396             @return: Y-axis scale
397        """
398        return self.yscale
399   
400    def set_xscale(self, scale='linear'):
401        """
402            Set the scale on x-axis
403            @param scale: the scale of x-axis
404        """
405        self.subplot.set_xscale(scale)
406        self.xscale = scale
407       
408    def get_xscale(self):
409        """
410             @return: x-axis scale
411        """
412        return self.xscale
413
414    def SetColor(self, rgbtuple):
415        """Set figure and canvas colours to be the same"""
416        if not rgbtuple:
417            rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
418        col = [c/255.0 for c in rgbtuple]
419        self.figure.set_facecolor(col)
420        self.figure.set_edgecolor(col)
421        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))
422
423    def _onSize(self, event):
424        self._resizeflag = True
425
426    def _onIdle(self, evt):
427        if self._resizeflag:
428            self._resizeflag = False
429            self._SetSize()
430            self.draw()
431
432    def _SetSize(self, pixels = None):
433        """
434        This method can be called to force the Plot to be a desired size, which defaults to
435        the ClientSize of the panel
436        """
437        if not pixels:
438            pixels = self.GetClientSize()
439        self.canvas.SetSize(pixels)
440        self.figure.set_size_inches(pixels[0]/self.figure.get_dpi(),
441        pixels[1]/self.figure.get_dpi())
442
443    def draw(self):
444        """Where the actual drawing happens"""
445        self.figure.canvas.draw_idle()
446       
447       
448    def onSaveImage(self, evt):
449        #figure.savefig
450        #print "Save image not implemented"
451        path = None
452        dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "*.png", wx.SAVE)
453        if dlg.ShowModal() == wx.ID_OK:
454            path = dlg.GetPath()
455            mypath = os.path.basename(path)
456            print path
457        dlg.Destroy()
458        if not path == None:
459            self.subplot.figure.savefig(path,dpi=300, facecolor='w', edgecolor='w',
460                                        orentation='portrait', papertype=None, format='png')
461       
462    def onContextMenu(self, event):
463        """
464            Default context menu for a plot panel
465        """
466        # Slicer plot popup menu
467        id = wx.NewId()
468        slicerpop = wx.Menu()
469        slicerpop.Append(id,'&Save image', 'Save image as PNG')
470        wx.EVT_MENU(self, id, self.onSaveImage)
471       
472        #id = wx.NewId()
473        #slicerpop.Append(id, '&Load 1D data file')
474        #wx.EVT_MENU(self, id, self._onLoad1DData)
475       
476        id = wx.NewId()
477        slicerpop.AppendSeparator()
478        slicerpop.Append(id, '&Properties')
479        wx.EVT_MENU(self, id, self._onProperties)
480       
481        id = wx.NewId()
482        slicerpop.AppendSeparator()
483        slicerpop.Append(id, '&Linear Fit')
484        wx.EVT_MENU(self, id, self.onFitting)
485       
486        id = wx.NewId()
487        slicerpop.AppendSeparator()
488        slicerpop.Append(id, '&Reset Graph')
489        wx.EVT_MENU(self, id, self.onResetGraph)
490       
491        pos = event.GetPosition()
492        pos = self.ScreenToClient(pos)
493        self.PopupMenu(slicerpop, pos)
494   
495    ## The following is plottable functionality
496
497
498    def properties(self,prop):
499        """Set some properties of the graph.
500       
501        The set of properties is not yet determined.
502        """
503        # The particulars of how they are stored and manipulated (e.g., do
504        # we want an inventory internally) is not settled.  I've used a
505        # property dictionary for now.
506        #
507        # How these properties interact with a user defined style file is
508        # even less clear.
509
510        # Properties defined by plot
511        self.subplot.set_xlabel(r"$%s$" % prop["xlabel"])
512        self.subplot.set_ylabel(r"$%s$" % prop["ylabel"])
513        self.subplot.set_title(prop["title"])
514
515        # Properties defined by user
516        #self.axes.grid(True)
517
518    def clear(self):
519        """Reset the plot"""
520       
521        # TODO: Redraw is brutal.  Render to a backing store and swap in
522        # TODO: rather than redrawing on the fly.
523        self.subplot.clear()
524        self.subplot.hold(True)
525   
526    def render(self):
527        """Commit the plot after all objects are drawn"""
528        # TODO: this is when the backing store should be swapped in.
529        from matplotlib.font_manager import FontProperties
530        self.subplot.legend(prop=FontProperties(size=10))
531        #self.subplot.legend()
532        pass
533
534    def xaxis(self,label,units):
535        """xaxis label and units.
536       
537        Axis labels know about units.
538       
539        We need to do this so that we can detect when axes are not
540        commesurate.  Currently this is ignored other than for formatting
541        purposes.
542        """
543        if units != "": label = label + " (" + units + ")"
544        self.subplot.set_xlabel(label)
545        pass
546   
547    def yaxis(self,label,units):
548        """yaxis label and units."""
549        if units != "": label = label + " (" + units + ")"
550        self.subplot.set_ylabel(label)
551        pass
552
553    def _connect_to_xlim(self,callback):
554        """Bind the xlim change notification to the callback"""
555        def process_xlim(axes):
556            lo,hi = subplot.get_xlim()
557            callback(lo,hi)
558        self.subplot.callbacks.connect('xlim_changed',process_xlim)
559   
560    #def connect(self,trigger,callback):
561    #    print "PlotPanel.connect???"
562    #    if trigger == 'xlim': self._connect_to_xlim(callback)
563
564    def points(self,x,y,dx=None,dy=None,color=0,symbol=0,label=None):
565        """Draw markers with error bars"""
566        self.subplot.set_yscale('linear')
567        self.subplot.set_xscale('linear')
568       
569        # Convert tuple (lo,hi) to array [(x-lo),(hi-x)]
570        if dx != None and type(dx) == type(()):
571            dx = nx.vstack((x-dx[0],dx[1]-x)).transpose()
572        if dy != None and type(dy) == type(()):
573            dy = nx.vstack((y-dy[0],dy[1]-y)).transpose()
574
575        if dx==None and dy==None:
576            h = self.subplot.plot(x,y,color=self._color(color),
577                                   marker=self._symbol(symbol),linestyle='',label=label)
578        else:
579            col = self._color(color)
580            self.subplot.errorbar(x, y, yerr=dy, xerr=None,
581             ecolor=col, capsize=2,linestyle='', barsabove=False,
582             mec=col, mfc=col,
583             marker=self._symbol(symbol),
584             lolims=False, uplims=False,
585             xlolims=False, xuplims=False,label=label)
586           
587        self.subplot.set_yscale(self.yscale)
588        self.subplot.set_xscale(self.xscale)
589
590    def curve(self,x,y,dy=None,color=0,symbol=0,label=None):
591        """Draw a line on a graph, possibly with confidence intervals."""
592        c = self._color(color)
593        self.subplot.set_yscale('linear')
594        self.subplot.set_xscale('linear')
595       
596        hlist = self.subplot.plot(x,y,color=c,marker='',linestyle='-',label=label)
597       
598        self.subplot.set_yscale(self.yscale)
599        self.subplot.set_xscale(self.xscale)
600
601    def _color(self,c):
602        """Return a particular colour"""
603        return self.colorlist[c%len(self.colorlist)]
604
605    def _symbol(self,s):
606        """Return a particular symbol"""
607        return self.symbollist[s%len(self.symbollist)]
608   
609    def _replot(self):
610        """
611            Rescale the plottables according to the latest
612            user selection and update the plot
613        """
614        self.graph.reset_scale()
615        self._onEVT_FUNC_PROPERTY(remove_fit=False)
616       
617        #TODO: Why do we have to have the following line?
618        self.fit_result.reset_view()
619       
620        self.graph.render(self)
621        self.subplot.figure.canvas.draw_idle()
622   
623    def _onEVT_FUNC_PROPERTY(self, remove_fit=True):
624        """
625             Receive the x and y transformation from myDialog,Transforms x and y in View
626              and set the scale   
627        """ 
628        list =[]
629        list = self.graph.returnPlottable()
630       
631        if remove_fit:
632            self.fit_result.x =[] 
633            self.fit_result.y =[] 
634            self.fit_result.dx=None
635            self.fit_result.dy=None
636            self.graph.delete(self.fit_result)
637       
638        for item in list:
639            item.setLabel(self.xLabel,self.yLabel)
640            if ( self.xLabel=="x" ):
641                item.transformX(transform.toX,transform.errToX)
642                self.set_xscale("linear")
643                name, units = item.get_xaxis()
644                self.graph.xaxis("%s" % name,  "%s" % units)
645               
646               
647            if ( self.xLabel=="x^(2)" ):
648                item.transformX(transform.toX2,transform.errToX2)
649                self.set_xscale('linear')
650                name, units = item.get_xaxis()
651                units=convertUnit(2,units) 
652                self.graph.xaxis("%s^{2}" % name,  "%s" % units)
653               
654               
655            if (self.xLabel=="log10(x)" ):
656                item.transformX(transform.toX,transform.errToX)
657                self.set_xscale("log")
658                name, units = item.get_xaxis() 
659                self.graph.xaxis("\log_{10}\ \  (%s)" % name,  "%s" % units)
660               
661               
662            if ( self.yLabel=="ln(y)" ):
663                item.transformY(transform.toLogX,transform.errToLogX)
664                self.set_yscale("linear")
665                name, units = item.get_yaxis()
666                self.graph.yaxis("log\ \ %s" % name,  "%s" % units)
667               
668               
669            if ( self.yLabel=="y" ):
670                item.transformY(transform.toX,transform.errToX)
671                self.set_yscale("linear")
672                name, units = item.get_yaxis()
673                self.graph.yaxis("%s" % name,  "%s" % units)
674               
675               
676            if ( self.yLabel=="log10(y)" ): 
677                item.transformY(transform.toX,transform.errToX)
678                self.set_yscale("log") 
679                name, units = item.get_yaxis()
680                self.graph.yaxis("\log_{10}\ \ (%s)" % name,  "%s" % units)
681               
682               
683            if ( self.yLabel=="y^(2)" ):
684                item.transformY( transform.toX2,transform.errToX2 )   
685                self.set_yscale("linear")
686                name, units = item.get_yaxis()
687                units=convertUnit(2,units) 
688                self.graph.yaxis("%s^{2}" % name,  "%s" % units)
689               
690               
691            if ( self.yLabel =="1/y"):
692                item.transformY(transform.toOneOverX,transform.errOneOverX )
693                self.set_yscale("linear")
694                name, units = item.get_yaxis()
695                units=convertUnit(-1,units)
696                self.graph.yaxis("1/%s" % name,  "%s" % units)
697               
698            if ( self.yLabel =="1/sqrt(y)" ):
699                item.transformY(transform.toOneOverSqrtX,transform.errOneOverSqrtX )
700                self.set_yscale("linear")
701                name, units = item.get_yaxis()
702                units=convertUnit(-0.5,units)
703                self.graph.yaxis("1/\sqrt{%s}" %name,  "%s" % units)
704               
705            if ( self.yLabel =="ln(y*x)"):
706                item.transformY( transform.toLogXY,transform.errToLogXY)
707                self.set_yscale("linear")
708                yname, yunits = item.get_yaxis()
709                xname, xunits = item.get_xaxis()
710                self.graph.yaxis("log\ (%s \ \ %s)" % (yname,xname),  "%s%s" % (yunits,xunits))
711               
712               
713            if ( self.yLabel =="ln(y*x^(2))"):
714                item.transformY( transform.toLogYX2,transform.errToLogYX2)
715                self.set_yscale("linear")
716                yname, yunits = item.get_yaxis()
717                xname, xunits = item.get_xaxis() 
718                xunits = convertUnit(2,xunits) 
719                self.graph.yaxis("Log (%s \ \ %s^{2})" % (yname,xname),  "%s%s" % (yunits,xunits))
720               
721           
722            if ( self.yLabel =="ln(y*x^(4))"):
723                item.transformY(transform.toLogYX4,transform.errToLogYX4)
724                self.set_yscale("linear")
725                yname, yunits = item.get_yaxis()
726                xname, xunits = item.get_xaxis()
727                xunits = convertUnit(4,xunits) 
728                self.graph.yaxis("Log (%s \ \ %s^{4})" % (yname,xname),  "%s%s" % (yunits,xunits))
729               
730            if ( self.viewModel == "Guinier lny vs x^(2)"):
731               
732                item.transformX(transform.toX2,transform.errToX2)
733                self.set_xscale('linear')
734                name, units = item.get_xaxis()
735                units = convertUnit(2,units) 
736                self.graph.xaxis("%s^{2}" % name,  "%s" % units)
737               
738               
739                item.transformY(transform.toLogX,transform.errToLogX )
740                self.set_yscale("linear")
741                name, units = item.get_yaxis()
742                self.graph.yaxis("$Log %s$" % name,  "%s" % units)
743               
744               
745            item.transformView()
746           
747         
748        self.resetFitView()   
749        self.prevXtrans = self.xLabel
750        self.prevYtrans = self.yLabel 
751        self.graph.render(self)
752        self.subplot.figure.canvas.draw_idle()
753       
754       
755   
756    def onFitDisplay(self, tempx,tempy,xminView,xmaxView,xmin,xmax,func):
757        """
758            Add a new plottable into the graph .In this case this plottable will be used
759            to fit some data
760            @param tempx: The x data of fit line
761            @param tempy: The y data of fit line
762            @param xminView: the lower bound of fitting range
763            @param xminView: the upper bound of  fitting range
764            @param xmin: the lowest value of data to fit to the line
765            @param xmax: the highest value of data to fit to the line
766        """
767        # Saving value to redisplay in Fit Dialog when it is opened again
768        self.Avalue,self.Bvalue,self.ErrAvalue,self.ErrBvalue,self.Chivalue=func
769        self.xminView=xminView
770        self.xmaxView=xmaxView
771        self.xmin= xmin
772        self.xmax= xmax
773        #In case need to change the range of data plotted
774        list =[]
775        list = self.graph.returnPlottable()
776        for item in list:
777            #item.onFitRange(xminView,xmaxView)
778            item.onFitRange(None,None)
779       
780        # Create new data plottable with result
781        self.fit_result.x =[] 
782        self.fit_result.y =[]
783        self.fit_result.x =tempx 
784        self.fit_result.y =tempy     
785        self.fit_result.dx=None
786        self.fit_result.dy=None
787        #Load the view with the new values
788        self.fit_result.reset_view()
789        # Add the new plottable to the graph
790        self.graph.add(self.fit_result) 
791        self.graph.render(self)
792        self.subplot.figure.canvas.draw_idle()
793       
794   
795    def onResetGraph(self,event):
796        """
797            Reset the graph by plotting the full range of data
798        """
799        list =[]
800        list = self.graph.returnPlottable()
801        for item in list:
802            item.onReset()
803        self.graph.render(self)
804        self.subplot.figure.canvas.draw_idle()
805       
806class NoRepaintCanvas(FigureCanvasWxAgg):
807    """We subclass FigureCanvasWxAgg, overriding the _onPaint method, so that
808    the draw method is only called for the first two paint events. After that,
809    the canvas will only be redrawn when it is resized.
810    """
811    def __init__(self, *args, **kwargs):
812        FigureCanvasWxAgg.__init__(self, *args, **kwargs)
813        self._drawn = 0
814
815    def _onPaint(self, evt):
816        """
817        Called when wxPaintEvt is generated
818        """
819        if not self._isRealized:
820            self.realize()
821        if self._drawn < 2:
822            self.draw(repaint = False)
823            self._drawn += 1
824        self.gui_repaint(drawDC=wx.PaintDC(self))
825           
Note: See TracBrowser for help on using the repository browser.