source: sasview/guitools/PlotPanel.py @ 4101eea

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

dragging working better

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