1 | import math |
---|
2 | import time |
---|
3 | import copy |
---|
4 | import numpy as np |
---|
5 | import wx |
---|
6 | import wx.aui |
---|
7 | import matplotlib as mpl |
---|
8 | import GSASIIgrid as G2gd |
---|
9 | import GSASIIcomp as G2cmp |
---|
10 | from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas |
---|
11 | from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx as Toolbar |
---|
12 | |
---|
13 | # useful degree trig functions |
---|
14 | sind = lambda x: math.sin(x*math.pi/180.) |
---|
15 | cosd = lambda x: math.cos(x*math.pi/180.) |
---|
16 | tand = lambda x: math.tan(x*math.pi/180.) |
---|
17 | asind = lambda x: 180.*math.asin(x)/math.pi |
---|
18 | acosd = lambda x: 180.*math.acos(x)/math.pi |
---|
19 | atan2d = lambda x,y: 180.*math.atan2(y,x)/math.pi |
---|
20 | atand = lambda x: 180.*math.atan(x)/math.pi |
---|
21 | |
---|
22 | class G2Plot(wx.Panel): |
---|
23 | |
---|
24 | def __init__(self,parent,id=-1,dpi=None,**kwargs): |
---|
25 | wx.Panel.__init__(self,parent,id=id,**kwargs) |
---|
26 | self.figure = mpl.figure.Figure(dpi=dpi,figsize=(5,7)) |
---|
27 | self.canvas = Canvas(self,-1,self.figure) |
---|
28 | self.toolbar = Toolbar(self.canvas) |
---|
29 | |
---|
30 | self.toolbar.Realize() |
---|
31 | |
---|
32 | sizer=wx.BoxSizer(wx.VERTICAL) |
---|
33 | sizer.Add(self.canvas,1,wx.EXPAND) |
---|
34 | sizer.Add(self.toolbar,0,wx.LEFT|wx.EXPAND) |
---|
35 | self.SetSizer(sizer) |
---|
36 | |
---|
37 | class G2PlotNoteBook(wx.Panel): |
---|
38 | def __init__(self,parent,id=-1): |
---|
39 | wx.Panel.__init__(self,parent,id=id) |
---|
40 | #so one can't delete a plot page!! |
---|
41 | self.nb = wx.aui.AuiNotebook(self, \ |
---|
42 | style=wx.aui.AUI_NB_DEFAULT_STYLE ^ wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB) |
---|
43 | sizer = wx.BoxSizer() |
---|
44 | sizer.Add(self.nb,1,wx.EXPAND) |
---|
45 | self.SetSizer(sizer) |
---|
46 | self.status = parent.CreateStatusBar() |
---|
47 | |
---|
48 | self.plotList = [] |
---|
49 | |
---|
50 | def add(self,name=""): |
---|
51 | page = G2Plot(self.nb) |
---|
52 | self.nb.AddPage(page,name) |
---|
53 | |
---|
54 | self.plotList.append(name) |
---|
55 | |
---|
56 | return page.figure |
---|
57 | |
---|
58 | def PlotSngl(self): |
---|
59 | from matplotlib.patches import Circle |
---|
60 | |
---|
61 | def OnSCMotion(event): |
---|
62 | xpos = event.xdata |
---|
63 | if xpos: |
---|
64 | xpos = round(xpos) #avoid out of frame mouse position |
---|
65 | ypos = round(event.ydata) |
---|
66 | zpos = Data['Layer'] |
---|
67 | if '100' in Data['Zone']: |
---|
68 | HKLtxt = '(%3d,%3d,%3d)'%(zpos,xpos,ypos) |
---|
69 | elif '010' in Data['Zone']: |
---|
70 | HKLtxt = '(%3d,%3d,%3d)'%(xpos,zpos,ypos) |
---|
71 | elif '001' in Data['Zone']: |
---|
72 | HKLtxt = '(%3d,%3d,%3d)'%(xpos,ypos,zpos) |
---|
73 | snglPage.canvas.SetToolTipString(HKLtxt) |
---|
74 | self.G2plotNB.status.SetFields(['HKL = '+HKLtxt,]) |
---|
75 | |
---|
76 | def OnSCPick(event): |
---|
77 | zpos = Data['Layer'] |
---|
78 | pos = event.artist.center |
---|
79 | if '100' in Data['Zone']: |
---|
80 | snglPage.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(zpos,pos[0],pos[1])) |
---|
81 | hkl = [zpos,pos[0],pos[1]] |
---|
82 | elif '010' in Data['Zone']: |
---|
83 | snglPage.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(pos[0],zpos,pos[1])) |
---|
84 | hkl = [pos[0],zpos,pos[1]] |
---|
85 | elif '001' in Data['Zone']: |
---|
86 | snglPage.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(pos[0],pos[1],zpos)) |
---|
87 | hkl = [pos[0],pos[1],zpos] |
---|
88 | h,k,l = hkl |
---|
89 | i = HKL.all(hkl) |
---|
90 | print i |
---|
91 | HKLtxt = '(%3d,%3d,%3d %10.2f %6.3f %10.2f)'%(h,k,l,Fosq,sig,Fcsq) |
---|
92 | self.G2plotNB.status.SetFields(['HKL, Fosq, sig, Fcsq = '+HKLtxt,]) |
---|
93 | |
---|
94 | |
---|
95 | def OnSCKeyPress(event): |
---|
96 | print event.key |
---|
97 | |
---|
98 | try: |
---|
99 | plotNum = self.G2plotNB.plotList.index('Structure Factors') |
---|
100 | snglPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
101 | snglPlot = snglPage.figure.gca() |
---|
102 | snglPlot.cla() |
---|
103 | except ValueError,error: |
---|
104 | snglPlot = self.G2plotNB.add('Structure Factors').gca() |
---|
105 | plotNum = self.G2plotNB.plotList.index('Structure Factors') |
---|
106 | snglPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
107 | snglPage.canvas.mpl_connect('key_press_event', OnSCKeyPress) |
---|
108 | snglPage.canvas.mpl_connect('pick_event', OnSCPick) |
---|
109 | snglPage.canvas.mpl_connect('motion_notify_event', OnSCMotion) |
---|
110 | snglPage.SetFocus() |
---|
111 | |
---|
112 | snglPlot.set_aspect(aspect='equal') |
---|
113 | HKLref = self.PatternTree.GetItemPyData(self.Sngl) |
---|
114 | Data = self.PatternTree.GetItemPyData( \ |
---|
115 | G2gd.GetPatternTreeItemId(self,self.Sngl, 'HKL Plot Controls')) |
---|
116 | Type = Data['Type'] |
---|
117 | scale = Data['Scale'] |
---|
118 | HKLmax = Data['HKLmax'] |
---|
119 | HKLmin = Data['HKLmin'] |
---|
120 | FosqMax = Data['FoMax'] |
---|
121 | FoMax = math.sqrt(FosqMax) |
---|
122 | ifFc = Data['ifFc'] |
---|
123 | xlabel = ['k, h=','h, k=','h, l='] |
---|
124 | ylabel = ['l','l','k'] |
---|
125 | zones = ['100','010','001'] |
---|
126 | pzone = [[1,2],[0,2],[0,1]] |
---|
127 | izone = zones.index(Data['Zone']) |
---|
128 | snglPlot.set_title(self.PatternTree.GetItemText(self.Sngl)[5:]) |
---|
129 | HKL = [] |
---|
130 | for H,Fosq,sig,Fcsq,x,x,x in HKLref: |
---|
131 | HKL.append(H) |
---|
132 | if H[izone] == Data['Layer']: |
---|
133 | B = 0 |
---|
134 | if Type == 'Fosq': |
---|
135 | A = scale*Fosq/FosqMax |
---|
136 | B = scale*Fcsq/FosqMax |
---|
137 | C = abs(A-B) |
---|
138 | elif Type == 'Fo': |
---|
139 | A = scale*math.sqrt(max(0,Fosq))/FoMax |
---|
140 | B = scale*math.sqrt(max(0,Fcsq))/FoMax |
---|
141 | C = abs(A-B) |
---|
142 | elif Type == '|DFsq|/sig': |
---|
143 | A = abs(Fosq-Fcsq)/(scale*sig) |
---|
144 | elif Type == '|DFsq|>sig': |
---|
145 | A = abs(Fosq-Fcsq)/(scale*sig) |
---|
146 | if A < 1.0: A = 0 |
---|
147 | elif Type == '|DFsq|>3sig': |
---|
148 | A = abs(Fosq-Fcsq)/(scale*sig) |
---|
149 | if A < 3.0: A = 0 |
---|
150 | xy = (H[pzone[izone][0]],H[pzone[izone][1]]) |
---|
151 | if A > 0.0: |
---|
152 | snglPlot.add_artist(Circle(xy,radius=A,ec='g',fc='w',picker=3)) |
---|
153 | if B: |
---|
154 | snglPlot.add_artist(Circle(xy,radius=B,ec='b',fc='w')) |
---|
155 | radius = C |
---|
156 | if radius > 0: |
---|
157 | if A > B: |
---|
158 | snglPlot.add_artist(Circle(xy,radius=radius,ec='r',fc='r')) |
---|
159 | else: |
---|
160 | snglPlot.add_artist(Circle(xy,radius=radius,ec='g',fc='g')) |
---|
161 | HKL = np.array(HKL) |
---|
162 | snglPlot.set_xlabel(xlabel[izone]+str(Data['Layer']),fontsize=12) |
---|
163 | snglPlot.set_ylabel(ylabel[izone],fontsize=12) |
---|
164 | snglPlot.set_xlim((HKLmin[pzone[izone][0]],HKLmax[pzone[izone][0]])) |
---|
165 | snglPlot.set_ylim((HKLmin[pzone[izone][1]],HKLmax[pzone[izone][1]])) |
---|
166 | snglPage.canvas.draw() |
---|
167 | |
---|
168 | def PlotImage(self): |
---|
169 | from matplotlib.patches import Ellipse,Arc |
---|
170 | |
---|
171 | def OnImMotion(event): |
---|
172 | imgPage.canvas.SetToolTipString('') |
---|
173 | size = len(self.ImageZ) |
---|
174 | if (xlim[0] < event.xdata < xlim[1]) & (ylim[0] > event.ydata > ylim[1]): |
---|
175 | Data = self.PatternTree.GetItemPyData( \ |
---|
176 | G2gd.GetPatternTreeItemId(self,self.Image, 'Image Controls')) |
---|
177 | imgPage.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
178 | item = self.itemPicked |
---|
179 | pixelSize = Data['pixelSize'] |
---|
180 | scalex = 1000./pixelSize[0] |
---|
181 | scaley = 1000./pixelSize[1] |
---|
182 | if item and self.PatternTree.GetItemText(self.PickId) == 'Image Controls': |
---|
183 | if 'Text' in str(item): |
---|
184 | imgPage.canvas.SetToolTipString('%8.3f %8.3fmm'%(event.xdata,event.ydata)) |
---|
185 | else: |
---|
186 | xcent,ycent = Data['center'] |
---|
187 | xpos = event.xdata-xcent |
---|
188 | ypos = event.ydata-ycent |
---|
189 | if 'line3' in str(item) or 'line4' in str(item) and not Data['fullIntegrate']: |
---|
190 | ang = int(atan2d(xpos,ypos)) |
---|
191 | imgPage.canvas.SetToolTipString('%6d deg'%(ang)) |
---|
192 | elif 'line1' in str(item) or 'line2' in str(item): |
---|
193 | tth = G2cmp.GetTth(event.xdata,event.ydata,Data) |
---|
194 | imgPage.canvas.SetToolTipString('%8.3fdeg'%(tth)) |
---|
195 | else: |
---|
196 | xpos = event.xdata |
---|
197 | ypos = event.ydata |
---|
198 | xpix = xpos*scalex |
---|
199 | ypix = ypos*scaley |
---|
200 | if (0 <= xpix <= size) and (0 <= ypix <= size): |
---|
201 | imgPage.canvas.SetToolTipString('%6d'%(self.ImageZ[ypix][xpix])) |
---|
202 | tth,azm,dsp = G2cmp.GetTthDspAzm(xpos,ypos,Data) |
---|
203 | Q = 2.*math.pi/dsp |
---|
204 | self.G2plotNB.status.SetFields(\ |
---|
205 | ['Detector 2-th =%9.2fdeg, dsp =%9.3fA, Q = %6.3fA-1, azm = %7.2fdeg'%(tth,dsp,Q,azm),]) |
---|
206 | |
---|
207 | def OnImPlotKeyPress(event): |
---|
208 | if self.PatternTree.GetItemText(self.PickId) == 'Image Controls': |
---|
209 | Data = self.PatternTree.GetItemPyData(self.PickId) |
---|
210 | pixelSize = Data['pixelSize'] |
---|
211 | size = len(self.ImageZ) |
---|
212 | Xpos = event.xdata |
---|
213 | if not Xpos: #got point out of frame |
---|
214 | return |
---|
215 | Ypos = event.ydata |
---|
216 | if event.key == 'm': |
---|
217 | print 'mask = ',Xpos,Ypos |
---|
218 | |
---|
219 | def OnImPick(event): |
---|
220 | if self.PatternTree.GetItemText(self.PickId) != 'Image Controls': |
---|
221 | return |
---|
222 | if self.itemPicked is not None: return |
---|
223 | pick = event.artist |
---|
224 | self.itemPicked = pick |
---|
225 | |
---|
226 | def OnImRelease(event): |
---|
227 | if self.PatternTree.GetItemText(self.PickId) != 'Image Controls': |
---|
228 | return |
---|
229 | Data = self.PatternTree.GetItemPyData(self.PickId) |
---|
230 | pixelSize = Data['pixelSize'] |
---|
231 | scalex = 1000./pixelSize[0] |
---|
232 | scaley = 1000./pixelSize[1] |
---|
233 | if self.itemPicked is None: |
---|
234 | size = len(self.ImageZ) |
---|
235 | Xpos = event.xdata |
---|
236 | if not (Xpos and self.ifGetRing): #got point out of frame |
---|
237 | return |
---|
238 | Ypos = event.ydata |
---|
239 | if Ypos and not imgPage.toolbar._active: #make sure zoom/pan not selected |
---|
240 | if event.button == 1: |
---|
241 | Xpix = Xpos*scalex |
---|
242 | Ypix = Ypos*scaley |
---|
243 | xpos,ypos,I,J = G2cmp.ImageLocalMax(self.ImageZ,20,Xpix,Ypix) |
---|
244 | if I and J: |
---|
245 | xpos /= scalex |
---|
246 | ypos /= scaley |
---|
247 | Data['ring'].append([xpos,ypos]) |
---|
248 | PlotImage(self) |
---|
249 | return |
---|
250 | else: |
---|
251 | xpos = event.xdata |
---|
252 | if xpos: #avoid out of frame mouse position |
---|
253 | ypos = event.ydata |
---|
254 | if self.ifGetRing: |
---|
255 | xypos = [xpos,ypos] |
---|
256 | rings = Data['ring'] |
---|
257 | for ring in rings: |
---|
258 | if np.allclose(ring,xypos,.01,0): |
---|
259 | rings.remove(ring) |
---|
260 | else: |
---|
261 | tth,azm,dsp = G2cmp.GetTthDspAzm(xpos,ypos,Data) |
---|
262 | if 'Line2D' in str(self.itemPicked): |
---|
263 | if 'line1' in str(self.itemPicked): |
---|
264 | Data['IOtth'][0] = tth |
---|
265 | elif 'line2' in str(self.itemPicked): |
---|
266 | Data['IOtth'][1] = tth |
---|
267 | elif 'line3' in str(self.itemPicked) and not Data['fullIntegrate']: |
---|
268 | Data['LRazimuth'][0] = int(azm) |
---|
269 | elif 'line4' in str(self.itemPicked) and not Data['fullIntegrate']: |
---|
270 | Data['LRazimuth'][1] = int(azm) |
---|
271 | |
---|
272 | if Data['LRazimuth'][1] < Data['LRazimuth'][0]: |
---|
273 | Data['LRazimuth'][1] += 360 |
---|
274 | if Data['IOtth'][0] > Data['IOtth'][1]: |
---|
275 | Data['IOtth'] = G2cmp.SwapXY(Data['IOtth'][0],Data['IOtth'][1]) |
---|
276 | |
---|
277 | self.InnerTth.SetValue("%8.2f" % (Data['IOtth'][0])) |
---|
278 | self.OuterTth.SetValue("%8.2f" % (Data['IOtth'][1])) |
---|
279 | self.Lazim.SetValue("%6d" % (Data['LRazimuth'][0])) |
---|
280 | self.Razim.SetValue("%6d" % (Data['LRazimuth'][1])) |
---|
281 | else: |
---|
282 | print event.xdata,event.ydata,event.button |
---|
283 | PlotImage(self) |
---|
284 | self.itemPicked = None |
---|
285 | |
---|
286 | try: |
---|
287 | plotNum = self.G2plotNB.plotList.index('2D Powder Image') |
---|
288 | imgPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
289 | imgPage.figure.clf() |
---|
290 | imgPlot = imgPage.figure.gca() |
---|
291 | if imgPage.views: |
---|
292 | imgPage.toolbar._views = copy.deepcopy(imgPage.views) |
---|
293 | view = imgPage.toolbar._views.forward() |
---|
294 | |
---|
295 | except ValueError,error: |
---|
296 | imgPlot = self.G2plotNB.add('2D Powder Image').gca() |
---|
297 | plotNum = self.G2plotNB.plotList.index('2D Powder Image') |
---|
298 | imgPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
299 | imgPage.canvas.mpl_connect('key_press_event', OnImPlotKeyPress) |
---|
300 | imgPage.canvas.mpl_connect('motion_notify_event', OnImMotion) |
---|
301 | imgPage.canvas.mpl_connect('pick_event', OnImPick) |
---|
302 | imgPage.canvas.mpl_connect('button_release_event', OnImRelease) |
---|
303 | imgPage.views = False |
---|
304 | view = False |
---|
305 | imgPage.SetFocus() |
---|
306 | |
---|
307 | imgPlot.set_title(self.PatternTree.GetItemText(self.Image)[4:]) |
---|
308 | size,self.ImageZ = self.PatternTree.GetItemPyData(self.Image) |
---|
309 | Data = self.PatternTree.GetItemPyData( \ |
---|
310 | G2gd.GetPatternTreeItemId(self,self.Image, 'Image Controls')) |
---|
311 | imScale = 1 |
---|
312 | if len(self.ImageZ) > 1024: |
---|
313 | imScale = len(self.ImageZ)/1024 |
---|
314 | pixelSize = Data['pixelSize'] |
---|
315 | scalex = 1000./pixelSize[0] |
---|
316 | scaley = 1000./pixelSize[1] |
---|
317 | xmax = len(self.ImageZ) |
---|
318 | Xmax = len(self.ImageZ)*pixelSize[0]/1000. |
---|
319 | xlim = (-0.5,Xmax-.5) |
---|
320 | ylim = (Xmax-.5,-0.5,) |
---|
321 | if self.Img: |
---|
322 | xlim = self.Img.axes.get_xlim() |
---|
323 | ylim = self.Img.axes.get_ylim() |
---|
324 | Imin,Imax = Data['range'][1] |
---|
325 | acolor = mpl.cm.get_cmap(Data['color']) |
---|
326 | xcent,ycent = Data['center'] |
---|
327 | imgPlot.set_xlabel('Image x-axis, mm',fontsize=12) |
---|
328 | imgPlot.set_ylabel('Image y-axis, mm',fontsize=12) |
---|
329 | A = G2cmp.ImageCompress(self.ImageZ,imScale) |
---|
330 | self.Img = imgPlot.imshow(A,aspect='equal',cmap=acolor, \ |
---|
331 | interpolation='nearest',vmin=Imin,vmax=Imax,extent=[0,Xmax,Xmax,0]) |
---|
332 | imgPlot.plot(xcent,ycent,'x') |
---|
333 | if Data['showLines']: |
---|
334 | LRAzim = Data['LRazimuth'] #NB: integers |
---|
335 | IOtth = Data['IOtth'] |
---|
336 | wave = Data['wavelength'] |
---|
337 | dspI = wave/(2.0*sind(IOtth[0]/2.0)) |
---|
338 | ellI = G2cmp.GetEllipse(dspI,Data) #=False if dsp didn't yield an ellipse (ugh! a parabola or a hyperbola) |
---|
339 | dspO = wave/(2.0*sind(IOtth[1]/2.0)) |
---|
340 | ellO = G2cmp.GetEllipse(dspO,Data) #Ditto & more likely for outer ellipse |
---|
341 | if Data['fullIntegrate']: |
---|
342 | Azm = np.array(range(0,361)) |
---|
343 | else: |
---|
344 | Azm = np.array(range(LRAzim[0],LRAzim[1]+1)) |
---|
345 | if ellI: |
---|
346 | xyI = [] |
---|
347 | for azm in Azm: |
---|
348 | xyI.append(G2cmp.GetDetectorXY(dspI,azm,Data)) |
---|
349 | xyI = np.array(xyI) |
---|
350 | arcxI,arcyI = xyI.T |
---|
351 | imgPlot.plot(arcxI,arcyI,picker=3) |
---|
352 | if ellO: |
---|
353 | xyO = [] |
---|
354 | for azm in Azm: |
---|
355 | xyO.append(G2cmp.GetDetectorXY(dspO,azm,Data)) |
---|
356 | xyO = np.array(xyO) |
---|
357 | arcxO,arcyO = xyO.T |
---|
358 | imgPlot.plot(arcxO,arcyO,picker=3) |
---|
359 | if ellO and ellI and not Data['fullIntegrate']: |
---|
360 | imgPlot.plot([arcxI[0],arcxO[0]],[arcyI[0],arcyO[0]],picker=3) |
---|
361 | imgPlot.plot([arcxI[-1],arcxO[-1]],[arcyI[-1],arcyO[-1]],picker=3) |
---|
362 | for xring,yring in Data['ring']: |
---|
363 | imgPlot.text(xring,yring,'+',color='b',ha='center',va='center',picker=3) |
---|
364 | if Data['setRings']: |
---|
365 | rings = np.concatenate((Data['rings']),axis=0) |
---|
366 | for xring,yring,dsp in rings: |
---|
367 | imgPlot.text(xring,yring,'+',ha='center',va='center') |
---|
368 | for ellipse in Data['ellipses']: |
---|
369 | cent,phi,[width,height],col = ellipse |
---|
370 | imgPlot.add_artist(Ellipse([cent[0],cent[1]],2*width,2*height,phi,ec=col,fc='none')) |
---|
371 | imgPlot.text(cent[0],cent[1],'+',color=col,ha='center',va='center') |
---|
372 | colorBar = imgPage.figure.colorbar(self.Img) |
---|
373 | if view: |
---|
374 | self.Img.axes.set_xlim(view[0][:2]) |
---|
375 | self.Img.axes.set_ylim(view[0][2:]) |
---|
376 | else: |
---|
377 | self.Img.axes.set_xlim(xlim) |
---|
378 | self.Img.axes.set_ylim(ylim) |
---|
379 | imgPage.canvas.draw() |
---|
380 | |
---|
381 | def PlotPeakWidths(self): |
---|
382 | PatternId = self.PatternId |
---|
383 | limitID = G2gd.GetPatternTreeItemId(self,PatternId, 'Limits') |
---|
384 | if limitID: |
---|
385 | limits = self.PatternTree.GetItemPyData(limitID) |
---|
386 | else: |
---|
387 | return |
---|
388 | instParms = self.PatternTree.GetItemPyData( \ |
---|
389 | G2gd.GetPatternTreeItemId(self,PatternId, 'Instrument Parameters')) |
---|
390 | if instParms[0][0] == 'PXC': |
---|
391 | lam = instParms[1][1] |
---|
392 | if len(instParms[1]) == 12: |
---|
393 | GU,GV,GW,LX,LY = instParms[0][6:11] |
---|
394 | else: |
---|
395 | GU,GV,GW,LX,LY = instParms[0][4:9] |
---|
396 | peakID = G2gd.GetPatternTreeItemId(self,PatternId, 'Peak List') |
---|
397 | if peakID: |
---|
398 | peaks = self.PatternTree.GetItemPyData(peakID) |
---|
399 | else: |
---|
400 | peaks = [] |
---|
401 | |
---|
402 | try: |
---|
403 | plotNum = self.G2plotNB.plotList.index('Peak Widths') |
---|
404 | pkwPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
405 | pkwPage.figure.clf() |
---|
406 | pkwPlot = pkwPage.figure.gca() |
---|
407 | except ValueError,error: |
---|
408 | pkwPlot = self.G2plotNB.add('Peak Widths').gca() |
---|
409 | plotNum = self.G2plotNB.plotList.index('Peak Widths') |
---|
410 | pkwPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
411 | pkwPage.SetFocus() |
---|
412 | |
---|
413 | pkwPage.canvas.SetToolTipString('') |
---|
414 | colors=['b','g','r','c','m','k'] |
---|
415 | Xmin,Xmax = limits[1] |
---|
416 | Xmin = min(0.5,max(Xmin,1)) |
---|
417 | Xmin /= 2 |
---|
418 | Xmax /= 2 |
---|
419 | nPts = 100 |
---|
420 | delt = (Xmax-Xmin)/nPts |
---|
421 | thetas = [] |
---|
422 | for i in range(nPts): |
---|
423 | thetas.append(Xmin+i*delt) |
---|
424 | X = [] |
---|
425 | Y = [] |
---|
426 | Z = [] |
---|
427 | W = [] |
---|
428 | sig = lambda Th,U,V,W: 1.17741*math.sqrt(U*tand(Th)**2+V*tand(Th)+W)*math.pi/18000. |
---|
429 | gam = lambda Th,X,Y: (X/cosd(Th)+Y*tand(Th))*math.pi/18000. |
---|
430 | gamFW = lambda s,g: math.exp(math.log(g**5+2.69269*g**4*s+2.42843*g**3*s**2+4.47163*g**2*s**3+0.07842*g*s**4+s**5)/5.) |
---|
431 | for theta in thetas: |
---|
432 | X.append(4.0*math.pi*sind(theta)/lam) #q |
---|
433 | s = sig(theta,GU,GV,GW) |
---|
434 | g = gam(theta,LX,LY) |
---|
435 | G = gamFW(g,s) |
---|
436 | Y.append(s/tand(theta)) |
---|
437 | Z.append(g/tand(theta)) |
---|
438 | W.append(G/tand(theta)) |
---|
439 | pkwPlot.set_title('Instrument and sample peak widths') |
---|
440 | pkwPlot.set_ylabel(r'$\Delta q/q, \Delta d/d$',fontsize=14) |
---|
441 | pkwPlot.set_xlabel(r'$q, \AA^{-1}$',fontsize=14) |
---|
442 | pkwPlot.plot(X,Y,color='r',label='Gaussian') |
---|
443 | pkwPlot.plot(X,Z,color='g',label='Lorentzian') |
---|
444 | pkwPlot.plot(X,W,color='b',label='G+L') |
---|
445 | X = [] |
---|
446 | Y = [] |
---|
447 | Z = [] |
---|
448 | W = [] |
---|
449 | for peak in peaks: |
---|
450 | X.append(4.0*math.pi*sind(peak[0]/2.0)/lam) |
---|
451 | s = 1.17741*math.sqrt(peak[4])*math.pi/18000. |
---|
452 | g = peak[6]*math.pi/18000. |
---|
453 | G = gamFW(g,s) |
---|
454 | Y.append(s/tand(peak[0]/2.)) |
---|
455 | Z.append(g/tand(peak[0]/2.)) |
---|
456 | W.append(G/tand(peak[0]/2.)) |
---|
457 | pkwPlot.plot(X,Y,'+',color='r',label='G peak') |
---|
458 | pkwPlot.plot(X,Z,'+',color='g',label='L peak') |
---|
459 | pkwPlot.plot(X,W,'+',color='b',label='G+L peak') |
---|
460 | pkwPlot.legend(loc='best') |
---|
461 | pkwPage.canvas.draw() |
---|
462 | |
---|
463 | def PlotPatterns(self,newPlot=False): |
---|
464 | |
---|
465 | def OnPick(event): |
---|
466 | if self.itemPicked is not None: return |
---|
467 | PatternId = self.PatternId |
---|
468 | PickId = self.PickId |
---|
469 | pick = event.artist |
---|
470 | mouse = event.mouseevent |
---|
471 | xpos = pick.get_xdata() |
---|
472 | ypos = pick.get_ydata() |
---|
473 | ind = event.ind |
---|
474 | view = pdrPage.toolbar._views.forward() |
---|
475 | if view and 'line2' in str(pick): #apply offset only for picked powder pattern points |
---|
476 | ind += np.searchsorted(xye[0],view[0][0]) |
---|
477 | xy = zip(xpos[ind],ypos[ind])[0] |
---|
478 | if self.PatternTree.GetItemText(PickId) == 'Peak List': |
---|
479 | if ind.all() != [0]: #picked a data point |
---|
480 | inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Instrument Parameters')) |
---|
481 | if len(inst[1]) == 10: |
---|
482 | ins = inst[1][4:10] |
---|
483 | else: |
---|
484 | ins = inst[1][6:12] |
---|
485 | sig = ins[0]*tand(xy[0]/2.0)**2+ins[1]*tand(xy[0]/2.0)+ins[2] |
---|
486 | gam = ins[3]/cosd(xy[0]/2.0)+ins[4]*tand(xy[0]/2.0) |
---|
487 | data = self.PatternTree.GetItemPyData(self.PickId) |
---|
488 | XY = [xy[0],0, xy[1],1, sig,0, gam,0, ins[5],0] #default refine intensity 1st |
---|
489 | data.append(XY) |
---|
490 | G2gd.UpdatePeakGrid(self,data) |
---|
491 | PlotPatterns(self) |
---|
492 | else: #picked a peak list line |
---|
493 | self.itemPicked = pick |
---|
494 | elif self.PatternTree.GetItemText(PickId) == 'Limits': |
---|
495 | if ind.all() != [0]: #picked a data point |
---|
496 | LimitId = G2gd.GetPatternTreeItemId(self,PatternId, 'Limits') |
---|
497 | data = self.PatternTree.GetItemPyData(LimitId) |
---|
498 | if mouse.button==1: |
---|
499 | data[1][0] = min(xy[0],data[1][1]) |
---|
500 | if mouse.button==3: |
---|
501 | data[1][1] = max(xy[0],data[1][0]) |
---|
502 | self.PatternTree.SetItemPyData(LimitId,data) |
---|
503 | G2gd.UpdateLimitsGrid(self,data) |
---|
504 | PlotPatterns(self) |
---|
505 | else: #picked a limit line |
---|
506 | self.itemPicked = pick |
---|
507 | |
---|
508 | def OnPlotKeyPress(event): |
---|
509 | if event.key == 'w': |
---|
510 | if self.Weight: |
---|
511 | self.Weight = False |
---|
512 | else: |
---|
513 | self.Weight = True |
---|
514 | print 'plot weighting:',self.Weight |
---|
515 | elif event.key == 'u' and self.Offset < 100.: |
---|
516 | self.Offset += 1. |
---|
517 | elif event.key == 'd' and self.Offset > 0.: |
---|
518 | self.Offset -= 1. |
---|
519 | elif event.key == 'c': |
---|
520 | print 'contouring' |
---|
521 | if self.Contour: |
---|
522 | self.Contour = False |
---|
523 | else: |
---|
524 | self.Contour = True |
---|
525 | else: |
---|
526 | event.Skip(True) |
---|
527 | PlotPatterns(self) |
---|
528 | |
---|
529 | def OnMotion(event): |
---|
530 | xpos = event.xdata |
---|
531 | if xpos: #avoid out of frame mouse position |
---|
532 | ypos = event.ydata |
---|
533 | wave = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))[0][1] |
---|
534 | dsp = 0.0 |
---|
535 | if abs(xpos) > 0.: |
---|
536 | dsp = wave/(2.*sind(abs(xpos)/2.0)) |
---|
537 | pdrPage.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
538 | self.G2plotNB.status.SetFields(['2-theta =%9.3f d =%9.5f Intensity =%9.1f'%(xpos,dsp,ypos),]) |
---|
539 | if self.itemPicked: |
---|
540 | pdrPage.canvas.SetToolTipString('%9.3f'%(xpos)) |
---|
541 | |
---|
542 | def OnRelease(event): |
---|
543 | if self.itemPicked is None: return |
---|
544 | xpos = event.xdata |
---|
545 | if xpos: #avoid out of frame mouse position |
---|
546 | lines = [] |
---|
547 | for line in self.Lines: lines.append(line.get_xdata()[0]) |
---|
548 | lineNo = lines.index(self.itemPicked.get_xdata()[0]) |
---|
549 | if lineNo in [0,1]: |
---|
550 | LimitId = G2gd.GetPatternTreeItemId(self,self.PatternId, 'Limits') |
---|
551 | data = self.PatternTree.GetItemPyData(LimitId) |
---|
552 | print 'limits',xpos |
---|
553 | data[1][lineNo] = xpos |
---|
554 | self.PatternTree.SetItemPyData(LimitId,data) |
---|
555 | if self.PatternTree.GetItemText(self.PickId) == 'Limits': |
---|
556 | G2gd.UpdateLimitsGrid(self,data) |
---|
557 | else: |
---|
558 | PeakId = G2gd.GetPatternTreeItemId(self,self.PatternId, 'Peak List') |
---|
559 | data = self.PatternTree.GetItemPyData(PeakId) |
---|
560 | print 'peaks',xpos |
---|
561 | data[lineNo-2][0] = xpos |
---|
562 | self.PatternTree.SetItemPyData(PeakId,data) |
---|
563 | G2gd.UpdatePeakGrid(self,data) |
---|
564 | PlotPatterns(self) |
---|
565 | self.itemPicked = None |
---|
566 | |
---|
567 | xylim = [] |
---|
568 | try: |
---|
569 | plotNum = self.G2plotNB.plotList.index('Powder Patterns') |
---|
570 | pdrPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
571 | if not newPlot: |
---|
572 | pdrPlot = pdrPage.figure.gca() #get previous powder plot & get limits |
---|
573 | xylim = pdrPlot.get_xlim(),pdrPlot.get_ylim() |
---|
574 | pdrPage.figure.clf() |
---|
575 | pdrPlot = pdrPage.figure.gca() #get a fresh plot after clf() |
---|
576 | except ValueError,error: |
---|
577 | newPlot = True |
---|
578 | pdrPlot = self.G2plotNB.add('Powder Patterns').gca() |
---|
579 | plotNum = self.G2plotNB.plotList.index('Powder Patterns') |
---|
580 | pdrPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
581 | pdrPage.canvas.mpl_connect('key_press_event', OnPlotKeyPress) |
---|
582 | pdrPage.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
583 | pdrPage.canvas.mpl_connect('pick_event', OnPick) |
---|
584 | pdrPage.canvas.mpl_connect('button_release_event', OnRelease) |
---|
585 | |
---|
586 | pdrPage.SetFocus() |
---|
587 | |
---|
588 | PickId = self.PickId |
---|
589 | PatternId = self.PatternId |
---|
590 | colors=['b','g','r','c','m','k'] |
---|
591 | PlotList = [] |
---|
592 | Lines = [] |
---|
593 | item, cookie = self.PatternTree.GetFirstChild(self.root) |
---|
594 | while item: |
---|
595 | if 'PWDR' in self.PatternTree.GetItemText(item): |
---|
596 | Pattern = self.PatternTree.GetItemPyData(item) |
---|
597 | Pattern.append(self.PatternTree.GetItemText(item)) |
---|
598 | PlotList.append(Pattern) |
---|
599 | item, cookie = self.PatternTree.GetNextChild(self.root, cookie) |
---|
600 | Ymax = 1.0 |
---|
601 | for Pattern in PlotList: |
---|
602 | xye = Pattern[1] |
---|
603 | Ymax = max(Ymax,max(xye[1])) |
---|
604 | offset = self.Offset*Ymax/100.0 |
---|
605 | pdrPlot.set_title('Powder Patterns') |
---|
606 | pdrPlot.set_xlabel(r'$\mathsf{2\theta}$',fontsize=14) |
---|
607 | pdrPlot.set_ylabel('Intensity',fontsize=12) |
---|
608 | if self.Contour: |
---|
609 | ContourZ = [] |
---|
610 | ContourY = [] |
---|
611 | Nseq = 0 |
---|
612 | for Pattern in PlotList: |
---|
613 | ifpicked = False |
---|
614 | LimitId = 0 |
---|
615 | xye = Pattern[1] |
---|
616 | if PickId: |
---|
617 | ifpicked = Pattern[2] == self.PatternTree.GetItemText(PatternId) |
---|
618 | LimitId = G2gd.GetPatternTreeItemId(self,PatternId, 'Limits') |
---|
619 | N = PlotList.index(Pattern) |
---|
620 | X = xye[0] |
---|
621 | Y = xye[1]+offset*N |
---|
622 | if LimitId: |
---|
623 | limits = self.PatternTree.GetItemPyData(LimitId) |
---|
624 | Lines.append(pdrPlot.axvline(limits[1][0],color='g',dashes=(5,5),picker=3.)) |
---|
625 | Lines.append(pdrPlot.axvline(limits[1][1],color='r',dashes=(5,5),picker=3.)) |
---|
626 | if self.Contour: |
---|
627 | ContourY.append(N) |
---|
628 | ContourZ.append(Y) |
---|
629 | ContourX = X |
---|
630 | Nseq += 1 |
---|
631 | pdrPlot.set_ylabel('Data sequence',fontsize=12) |
---|
632 | else: |
---|
633 | if ifpicked: |
---|
634 | Z = xye[3]+offset*N |
---|
635 | W = xye[4]+offset*N |
---|
636 | D = xye[5]+offset*N |
---|
637 | if self.Weight: |
---|
638 | W2 = np.sqrt(xye[2]) |
---|
639 | D *= W2 |
---|
640 | pdrPlot.plot(X,Y,colors[N%6]+'+',picker=3.,clip_on=False) |
---|
641 | pdrPlot.plot(X,Z,colors[(N+1)%6],picker=False) |
---|
642 | pdrPlot.plot(X,W,colors[(N+2)%6],picker=False) |
---|
643 | pdrPlot.plot(X,D,colors[(N+3)%6],picker=False) |
---|
644 | pdrPlot.axhline(0.,color=wx.BLACK) |
---|
645 | pdrPage.canvas.SetToolTipString('') |
---|
646 | if self.PatternTree.GetItemText(PickId) == 'Peak List': |
---|
647 | tip = 'On data point: Pick peak - L or R MB.On line: MB down to move' |
---|
648 | pdrPage.canvas.SetToolTipString(tip) |
---|
649 | data = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Peak List')) |
---|
650 | for item in data: |
---|
651 | Lines.append(pdrPlot.axvline(item[0],color=colors[N%6],picker=2.)) |
---|
652 | if self.PatternTree.GetItemText(PickId) == 'Limits': |
---|
653 | tip = 'On data point: Lower limit - L MB; Upper limit - R MB. On limit: MB down to move' |
---|
654 | pdrPage.canvas.SetToolTipString(tip) |
---|
655 | data = self.LimitsTable.GetData() |
---|
656 | else: |
---|
657 | pdrPlot.plot(X,Y,colors[N%6],picker=False) |
---|
658 | if PickId and self.PatternTree.GetItemText(PickId) in ['Index Peak List','Unit Cells List']: |
---|
659 | peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Index Peak List')) |
---|
660 | for peak in peaks: |
---|
661 | pdrPlot.axvline(peak[0],color='b') |
---|
662 | for hkl in self.HKL: |
---|
663 | pdrPlot.axvline(hkl[5],color='r',dashes=(5,5)) |
---|
664 | if self.Contour: |
---|
665 | acolor = mpl.cm.get_cmap('Paired') |
---|
666 | pdrPlot.contourf(ContourX,ContourY,ContourZ,cmap=acolor) |
---|
667 | # pdrPlot.set_ylim(0,Nseq-1) |
---|
668 | else: |
---|
669 | self.Lines = Lines |
---|
670 | if not newPlot: |
---|
671 | pdrPage.toolbar.push_current() |
---|
672 | pdrPlot.set_xlim(xylim[0]) |
---|
673 | pdrPlot.set_ylim(xylim[1]) |
---|
674 | xylim = [] |
---|
675 | pdrPage.toolbar.push_current() |
---|
676 | pdrPage.toolbar.draw() |
---|
677 | else: |
---|
678 | pdrPage.canvas.draw() |
---|
679 | |
---|
680 | |
---|
681 | self.Pwdr = True |
---|
682 | |
---|
683 | def PlotPowderLines(self): |
---|
684 | |
---|
685 | def OnMotion(event): |
---|
686 | xpos = event.xdata |
---|
687 | if xpos: #avoid out of frame mouse position |
---|
688 | pksPage.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
689 | self.G2plotNB.status.SetFields(['2-theta =%9.3f '%(xpos,),]) |
---|
690 | |
---|
691 | try: |
---|
692 | plotNum = self.G2plotNB.plotList.index('Powder Lines') |
---|
693 | pksPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
694 | pksPage.figure.clf() |
---|
695 | pksPlot = pksPage.figure.gca() |
---|
696 | except ValueError,error: |
---|
697 | newPlot = True |
---|
698 | pksPlot = self.G2plotNB.add('Powder Lines').gca() |
---|
699 | plotNum = self.G2plotNB.plotList.index('Powder Lines') |
---|
700 | pksPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
701 | pksPage.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
702 | |
---|
703 | pksPage.SetFocus() |
---|
704 | pksPlot.set_title('Powder Pattern Lines') |
---|
705 | pksPlot.set_xlabel(r'$\mathsf{2\theta}$',fontsize=14) |
---|
706 | PickId = self.PickId |
---|
707 | PatternId = self.PatternId |
---|
708 | peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Index Peak List')) |
---|
709 | for peak in peaks: |
---|
710 | pksPlot.axvline(peak[0],color='b') |
---|
711 | for hkl in self.HKL: |
---|
712 | pksPlot.axvline(hkl[5],color='r',dashes=(5,5)) |
---|
713 | xmin = peaks[0][0] |
---|
714 | xmax = peaks[-1][0] |
---|
715 | delt = xmax-xmin |
---|
716 | xlim = [max(0,xmin-delt/20.),min(180.,xmax+delt/20.)] |
---|
717 | pksPlot.set_xlim(xlim) |
---|
718 | pksPage.canvas.draw() |
---|
719 | |
---|
720 | |
---|
721 | def PlotTRImage(self): |
---|
722 | |
---|
723 | def OnMotion(event): |
---|
724 | trimgPage.canvas.SetToolTipString('') |
---|
725 | trimgPage.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
726 | azm = event.xdata |
---|
727 | tth = event.ydata |
---|
728 | if azm and tth: |
---|
729 | self.G2plotNB.status.SetFields(\ |
---|
730 | ['Detector 2-th =%9.2fdeg, azm = %7.2fdeg'%(tth,azm),]) |
---|
731 | |
---|
732 | def OnPick(event): |
---|
733 | if self.PatternTree.GetItemText(self.PickId) != 'Image Controls': |
---|
734 | return |
---|
735 | if self.itemPicked is not None: return |
---|
736 | pick = event.artist |
---|
737 | self.itemPicked = pick |
---|
738 | |
---|
739 | def OnRelease(event): |
---|
740 | if self.PatternTree.GetItemText(self.PickId) != 'Image Controls': |
---|
741 | return |
---|
742 | Data = self.PatternTree.GetItemPyData(self.PickId) |
---|
743 | if self.itemPicked: |
---|
744 | xpos = event.xdata |
---|
745 | if xpos: #avoid out of frame mouse position |
---|
746 | ypos = event.ydata |
---|
747 | if 'Line2D' in str(self.itemPicked): |
---|
748 | if 'line0' in str(self.itemPicked): |
---|
749 | Data['IOtth'][0] = ypos |
---|
750 | elif 'line1' in str(self.itemPicked): |
---|
751 | Data['IOtth'][1] = ypos |
---|
752 | elif 'line2' in str(self.itemPicked) and not Data['fullIntegrate']: |
---|
753 | Data['LRazimuth'][0] = int(xpos) |
---|
754 | elif 'line3' in str(self.itemPicked) and not Data['fullIntegrate']: |
---|
755 | Data['LRazimuth'][1] = int(xpos) |
---|
756 | |
---|
757 | if Data['LRazimuth'][1] < Data['LRazimuth'][0]: |
---|
758 | Data['LRazimuth'][1] += 360 |
---|
759 | if Data['IOtth'][0] > Data['IOtth'][1]: |
---|
760 | Data['IOtth'] = G2cmp.SwapXY(Data['IOtth'][0],Data['IOtth'][1]) |
---|
761 | |
---|
762 | self.InnerTth.SetValue("%8.2f" % (Data['IOtth'][0])) |
---|
763 | self.OuterTth.SetValue("%8.2f" % (Data['IOtth'][1])) |
---|
764 | self.Lazim.SetValue("%6d" % (Data['LRazimuth'][0])) |
---|
765 | self.Razim.SetValue("%6d" % (Data['LRazimuth'][1])) |
---|
766 | else: |
---|
767 | print event.xdata,event.ydata,event.button |
---|
768 | PlotTRImage(self) |
---|
769 | self.itemPicked = None |
---|
770 | |
---|
771 | try: |
---|
772 | plotNum = self.G2plotNB.plotList.index('2D Transformed Powder Image') |
---|
773 | trimgPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
774 | trimgPage.figure.clf() |
---|
775 | trimgPlot = trimgPage.figure.gca() |
---|
776 | if trimgPage.views: |
---|
777 | trimgPage.toolbar._views = copy.deepcopy(trimgPage.views) |
---|
778 | view = trimgPage.toolbar._views.forward() |
---|
779 | |
---|
780 | except ValueError,error: |
---|
781 | trimgPlot = self.G2plotNB.add('2D Transformed Powder Image').gca() |
---|
782 | plotNum = self.G2plotNB.plotList.index('2D Transformed Powder Image') |
---|
783 | trimgPage = self.G2plotNB.nb.GetPage(plotNum) |
---|
784 | trimgPage.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
785 | trimgPage.canvas.mpl_connect('pick_event', OnPick) |
---|
786 | trimgPage.canvas.mpl_connect('button_release_event', OnRelease) |
---|
787 | trimgPage.views = False |
---|
788 | view = False |
---|
789 | trimgPage.SetFocus() |
---|
790 | |
---|
791 | data = self.PatternTree.GetItemPyData(self.PickId) |
---|
792 | image = self.ImageZ |
---|
793 | Iz = len(image) |
---|
794 | Imin,Imax = data['range'][1] |
---|
795 | step = (Imax-Imin)/5. |
---|
796 | V = np.arange(Imin,Imax,step) |
---|
797 | acolor = mpl.cm.get_cmap('Paired') |
---|
798 | trimgPlot.set_xlabel('azimuth',fontsize=12) |
---|
799 | trimgPlot.set_ylabel('2-theta',fontsize=12) |
---|
800 | trimgPlot.contour(self.TA[1],self.TA[0],image,V,cmap=acolor) |
---|
801 | if data['showLines']: |
---|
802 | IOtth = data['IOtth'] |
---|
803 | LRAzim = data['LRazimuth'] #NB: integers |
---|
804 | trimgPlot.plot([LRAzim[0],LRAzim[1]],[IOtth[0],IOtth[0]],picker=True) |
---|
805 | trimgPlot.plot([LRAzim[0],LRAzim[1]],[IOtth[1],IOtth[1]],picker=True) |
---|
806 | trimgPlot.plot([LRAzim[0],LRAzim[0]],[IOtth[0],IOtth[1]],picker=True) |
---|
807 | trimgPlot.plot([LRAzim[1],LRAzim[1]],[IOtth[0],IOtth[1]],picker=True) |
---|
808 | trimgPage.canvas.draw() |
---|
809 | |
---|
810 | |
---|