source: sasview/guitools/PlotPanel.py @ 06290c8

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

more modification on the drag

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