source: sasview/guitools/PlotPanel.py @ df25521

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

dragging added

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