Coverage for larch/wxlib/xafsplots.py: 29%
555 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
1#!/usr/bin/env python
2"""
3Plotting macros for XAFS data sets and fits
5 Function Description of what is plotted
6 ---------------- -----------------------------------------------------
7 plot_mu() mu(E) for XAFS data group in various forms
8 plot_bkg() mu(E) and background mu0(E) for XAFS data group
9 plot_chik() chi(k) for XAFS data group
10 plot_chie() chi(E) for XAFS data group
11 plot_chir() chi(R) for XAFS data group
12 plot_chifit() chi(k) and chi(R) for fit to feffit dataset
13 plot_path_k() chi(k) for a single path of a feffit dataset
14 plot_path_r() chi(R) for a single path of a feffit dataset
15 plot_paths_k() chi(k) for model and all paths of a feffit dataset
16 plot_paths_r() chi(R) for model and all paths of a feffit dataset
17 plot_diffkk() plots from DIFFKK
18 ---------------- -----------------------------------------------------
19"""
21from pathlib import Path
22from numpy import gradient, ndarray, diff, where, arange, argmin
23from matplotlib.ticker import FuncFormatter
25from larch import Group
26from larch.math import (index_of, index_nearest, interp)
27from larch.xafs import cauchy_wavelet, etok, ktoe
29try:
30 import wx
31 HAS_WXPYTHON = True
32except ImportError:
33 HAS_WXPYTHON = False
35if HAS_WXPYTHON:
36 from .plotter import (get_display, _plot, _oplot, _newplot, _fitplot,
37 _plot_text, _plot_marker, _plot_arrow,
38 _plot_axvline, _plot_axhline, _imshow)
39else:
40 def nullfunc(*args, **kws): pass
42 get_display = _plot = _oplot = _newplot = nullfunc
43 _fitplot = _plot_text = _plot_marker = nullfunc
44 _plot_arrow = _plot_axvline = _plot_axhline = nullfunc
48LineColors = ('#1f77b4', '#d62728', '#2ca02c', '#ff7f0e', '#9467bd',
49 '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf')
51# common XAFS plot labels
52def chirlab(kweight, show_mag=True, show_real=False, show_imag=False):
53 """generate chi(R) label for a kweight
55 Arguments
56 ----------
57 kweight k-weight to use (required)
58 show_mag bool whether to plot |chi(R)| [True]
59 show_real bool whether to plot Re[chi(R)] [False]
60 show_imag bool whether to plot Im[chi(R)] [False]
61 """
62 ylab = []
63 if show_mag: ylab.append(plotlabels.chirmag)
64 if show_real: ylab.append(plotlabels.chirre)
65 if show_imag: ylab.append(plotlabels.chirim)
66 if len(ylab) > 1: ylab = [plotlabels.chir]
67 return ylab[0].format(kweight+1)
68#enddef
70plotlabels = Group(k = r'$k \rm\,(\AA^{-1})$',
71 r = r'$R \rm\,(\AA)$',
72 energy = r'$E\rm\,(eV)$',
73 ewithk = r'$E\rm\,(eV)$' + '\n' + r'$[k \rm\,(\AA^{-1})]$',
74 i0 = r'$I_0(E)$',
75 mu = r'$\mu(E)$',
76 norm = r'normalized $\mu(E)$',
77 flat = r'flattened $\mu(E)$',
78 deconv = r'deconvolved $\mu(E)$',
79 dmude = r'$d\mu_{\rm norm}(E)/dE$',
80 d2mude = r'$d^2\mu_{\rm norm}(E)/dE^2$',
81 chie = r'$\chi(E)$',
82 chie0 = r'$\chi(E)$',
83 chie1 = r'$E\chi(E) \rm\, (eV)$',
84 chiew = r'$E^{{{0:g}}}\chi(E) \rm\,(eV^{{{0:g}}})$',
85 chikw = r'$k^{{{0:g}}}\chi(k) \rm\,(\AA^{{-{0:g}}})$',
86 chi0 = r'$\chi(k)$',
87 chi1 = r'$k\chi(k) \rm\,(\AA^{-1})$',
88 chi2 = r'$k^2\chi(k) \rm\,(\AA^{-2})$',
89 chi3 = r'$k^3\chi(k) \rm\,(\AA^{-3})$',
90 chir = r'$\chi(R) \rm\,(\AA^{{-{0:g}}})$',
91 chirmag = r'$|\chi(R)| \rm\,(\AA^{{-{0:g}}})$',
92 chirre = r'${{\rm Re}}[\chi(R)] \rm\,(\AA^{{-{0:g}}})$',
93 chirim = r'${{\rm Im}}[\chi(R)] \rm\,(\AA^{{-{0:g}}})$',
94 chirpha = r'${{\rm Phase}}[\chi(R)] \rm\,(\AA^{{-{0:g}}})$',
95 e0color = '#B2B282',
96 chirlab = chirlab,
97 x = r'$x$',
98 y = r'$y$',
99 xdat = r'$x$',
100 ydat = r'$y$',
101 xplot = r'$x$',
102 yplot= r'$y$',
103 ynorm = r'scaled $y$',
104 xshift = r'shifted $x$',
105 dydx = r'$dy/dx$',
106 d2ydx = r'$d^2y/dx^2$',
107 )
109def safetitle(t):
110 if "'" in t:
111 t = t.replace("'", "\\'")
112 return t
114def _get_title(dgroup, title=None):
115 """get best title for group"""
116 if title is not None:
117 return safetitle(title)
118 data_group = getattr(dgroup, 'data', None)
120 for attr in ('title', 'plot_title', 'filename', 'name', '__name__'):
121 t = getattr(dgroup, attr, None)
122 if t is not None:
123 if attr == 'filename':
124 t = '/'.join(Path(t).absolute().parts[-2:])
125 return safetitle(t)
126 if data_group is not None:
127 t = getattr(data_group, attr, None)
128 if t is not None:
129 return t
130 return safetitle(repr(dgroup))
133def _get_kweight(dgroup, kweight=None):
134 if kweight is not None:
135 return kweight
136 callargs = getattr(dgroup, 'callargs', None)
137 ftargs = getattr(callargs, 'xftf', {'kweight':0})
138 return ftargs['kweight']
141def _get_erange(dgroup, emin=None, emax=None):
142 """get absolute emin/emax for data range, allowing using
143 values relative to e0.
144 """
145 dat_emin, dat_emax = min(dgroup.energy)-100, max(dgroup.energy)+100
146 e0 = getattr(dgroup, 'e0', 0.0)
147 if emin is not None:
148 if not (emin > dat_emin and emin < dat_emax):
149 if emin+e0 > dat_emin and emin+e0 < dat_emax:
150 emin += e0
151 if emax is not None:
152 if not (emax > dat_emin and emax < dat_emax):
153 if emax+e0 > dat_emin and emax+e0 < dat_emax:
154 emax += e0
155 return emin, emax
156#enddef
158def redraw(win=1, xmin=None, xmax=None, ymin=None, ymax=None,
159 dymin=None, dymax=None,
160 show_legend=True, stacked=False, _larch=None):
161 disp = get_display(win=win, stacked=stacked, _larch=_larch)
162 if disp is None:
163 return
164 panel = disp.panel
165 panel.conf.show_legend = show_legend
166 if (xmin is not None or xmax is not None or
167 ymin is not None or ymax is not None):
168 panel.set_xylims((xmin, xmax, ymin, ymax))
169 if stacked:
170 disp.panel_bot.set_xylims((xmin, xmax, dymin, dymax))
172 panel.unzoom_all()
173 panel.reset_formats()
174 if stacked:
175 disp.panel_bot.unzoom_all()
176 disp.panel_bot.reset_formats()
177 if show_legend: # note: draw_legend *will* redraw the canvas
178 panel.conf.draw_legend()
179 else:
180 panel.canvas.draw()
181 if stacked:
182 disp.panel_bot.canvas.draw()
184 #endif
185#enddef
188def plot_mu(dgroup, show_norm=False, show_flat=False, show_deriv=False,
189 show_pre=False, show_post=False, show_e0=False, with_deriv=False,
190 emin=None, emax=None, label='mu', new=True, delay_draw=False,
191 offset=0, title=None, win=1, _larch=None):
192 """
193 plot_mu(dgroup, norm=False, deriv=False, show_pre=False, show_post=False,
194 show_e0=False, show_deriv=False, emin=None, emax=None, label=None,
195 new=True, win=1)
197 Plot mu(E) for an XAFS data group in various forms
199 Arguments
200 ----------
201 dgroup group of XAFS data after pre_edge() results (see Note 1)
202 show_norm bool whether to show normalized data [False]
203 show_flat bool whether to show flattened, normalized data [False]
204 show_deriv bool whether to show derivative of normalized data [False]
205 show_pre bool whether to show pre-edge curve [False]
206 show_post bool whether to show post-edge curve [False]
207 show_e0 bool whether to show E0 [False]
208 with_deriv bool whether to show deriv (dmu/de) together with mu [False]
209 emin min energy to show, absolute or relative to E0 [None, start of data]
210 emax max energy to show, absolute or relative to E0 [None, end of data]
211 label string for label [None: 'mu', `dmu/dE', or 'mu norm']
212 title string for plot title [None, may use filename if available]
213 new bool whether to start a new plot [True]
214 delay_draw bool whether to delay draw until more traces are added [False]
215 offset vertical offset to use for y-array [0]
216 win integer plot window to use [1]
218 Notes
219 -----
220 1. The input data group must have the following attributes:
221 energy, mu, norm, e0, pre_edge, edge_step
222 """
223 if hasattr(dgroup, 'mu'):
224 mu = dgroup.mu
225 elif hasattr(dgroup, 'mutrans'):
226 mu = dgroup.mutrans
227 elif hasattr(dgroup, 'mufluor'):
228 mu = dgroup.mufluor
229 else:
230 raise ValueError("XAFS data group has no array for mu")
231 #endif
232 ylabel = plotlabels.mu
233 if label is None:
234 label = getattr(dgroup, 'filename', 'mu')
235 #endif
236 if show_deriv:
237 mu = dgroup.dmude
238 ylabel = "%s (deriv)" % ylabel
239 dlabel = plotlabels.dmude
240 elif show_norm:
241 mu = dgroup.norm
242 ylabel = "%s (norm)" % ylabel
243 dlabel = plotlabels.norm
244 #endif
245 elif show_flat:
246 mu = dgroup.flat
247 ylabel = "%s (flat)" % ylabel
248 dlabel = plotlabels.flat
249 #endif
250 emin, emax = _get_erange(dgroup, emin, emax)
251 title = _get_title(dgroup, title=title)
253 opts = dict(win=win, show_legend=True, linewidth=3,
254 title=title, xmin=emin, xmax=emax,
255 delay_draw=True, _larch=_larch)
257 _plot(dgroup.energy, mu+offset, xlabel=plotlabels.energy, ylabel=ylabel,
258 label=label, zorder=20, new=new, **opts)
260 if with_deriv:
261 dmu = dgroup.dmude
262 _plot(dgroup.energy, dmu+offset, ylabel=plotlabels.dmude,
263 label='%s (deriv)' % label, zorder=18, side='right', **opts)
264 #endif
265 if (not show_norm and not show_deriv):
266 if show_pre:
267 _plot(dgroup.energy, dgroup.pre_edge+offset, label='pre_edge',
268 zorder=18, **opts)
269 #endif
270 if show_post:
271 _plot(dgroup.energy, dgroup.post_edge+offset, label='post_edge',
272 zorder=18, **opts)
273 if show_pre:
274 i = index_of(dgroup.energy, dgroup.e0)
275 ypre = dgroup.pre_edge[i]
276 ypost = dgroup.post_edge[i]
277 _plot_arrow(dgroup.e0, ypre, dgroup.e0+offset, ypost,
278 color=plotlabels.e0color, width=0.25,
279 head_width=0, zorder=3, win=win, _larch=_larch)
280 #endif
281 #endif
282 #endif
283 if show_e0:
284 _plot_axvline(dgroup.e0, zorder=2, size=3,
285 label='E0', color=plotlabels.e0color, win=win,
286 _larch=_larch)
287 disp = get_display(win=win, _larch=_larch)
288 if disp is not None:
289 disp.panel.conf.draw_legend()
290 redraw(win=win, xmin=emin, xmax=emax, _larch=_larch)
291#enddef
293def plot_bkg(dgroup, norm=True, emin=None, emax=None, show_e0=False, show_ek0=False,
294 label=None, title=None, new=True, delay_draw=False, offset=0,
295 win=1, _larch=None):
296 """
297 plot_bkg(dgroup, norm=True, emin=None, emax=None, show_e0=False, label=None, new=True, win=1):
299 Plot mu(E) and background mu0(E) for XAFS data group
301 Arguments
302 ----------
303 dgroup group of XAFS data after autobk() results (see Note 1)
304 norm bool whether to show normalized data [True]
305 emin min energy to show, absolute or relative to E0 [None, start of data]
306 emax max energy to show, absolute or relative to E0 [None, end of data]
307 show_e0 bool whether to show E0 [False]
308 show_ek0 bool whether to show EK0 [False]
309 label string for label [``None``: 'mu']
310 title string for plot titlte [None, may use filename if available]
311 new bool whether to start a new plot [True]
312 delay_draw bool whether to delay draw until more traces are added [False]
313 offset vertical offset to use for y-array [0]
314 win integer plot window to use [1]
316 Notes
317 -----
318 1. The input data group must have the following attributes:
319 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
320 """
321 if hasattr(dgroup, 'mu'):
322 mu = dgroup.mu
323 elif hasattr(dgroup, 'mutrans'):
324 mu = dgroup.mutrans
325 else:
326 raise ValueError("XAFS data group has no array for mu")
327 #endif
329 bkg = dgroup.bkg
330 ylabel = plotlabels.mu
331 if label is None:
332 label = 'mu'
333 #endif
334 emin, emax = _get_erange(dgroup, emin, emax)
335 if norm:
336 mu = dgroup.norm
337 bkg = (dgroup.bkg - dgroup.pre_edge) / dgroup.edge_step
338 ylabel = "%s (norm)" % ylabel
339 label = "%s (norm)" % label
340 #endif
341 title = _get_title(dgroup, title=title)
342 opts = dict(win=win, show_legend=True, linewidth=3,
343 delay_draw=True, _larch=_larch)
344 _plot(dgroup.energy, mu+offset, xlabel=plotlabels.energy, ylabel=ylabel,
345 title=title, label=label, zorder=20, new=new, xmin=emin, xmax=emax,
346 **opts)
347 ymin, ymax = None, None
348 disp = get_display(win=win, _larch=_larch)
349 if disp is not None:
350 xylims = disp.panel.get_viewlimits()
351 ymin, ymax = xylims[2], xylims[3]
352 _plot(dgroup.energy, bkg+offset, zorder=18, label='bkg', **opts)
354 e0val, e0label = None, 'E0'
355 if show_e0 and hasattr(dgroup, 'e0'):
356 e0val = dgroup.e0
357 elif show_ek0 and hasattr(dgroup, 'ek0'):
358 e0val, e0label = dgroup.ek0, 'EK0'
360 if e0val is not None:
361 ie0 = index_of(dgroup.energy, e0val)
362 ee0 = dgroup.energy[ie0]
363 me0 = mu[ie0] + offset
364 disp.panel.axes.plot([ee0], [me0], marker='o',
365 markersize=5, label='_nolegend_',
366 markerfacecolor='#808080',
367 markeredgecolor='#A03030')
369 if disp is not None:
370 disp.panel.conf.draw_legend()
371 #endif
372 redraw(win=win, xmin=emin, xmax=emax, ymin=ymin, ymax=ymax, _larch=_larch)
373#enddef
375def plot_chie(dgroup, emin=-5, emax=None, label=None, title=None,
376 eweight=0, show_k=True, new=True, delay_draw=False,
377 offset=0, win=1, _larch=None):
378 """
379 plot_chie(dgroup, emin=None, emax=None, label=None, new=True, win=1):
381 Plot chi(E) for XAFS data group
383 Arguments
384 ----------
385 dgroup group of XAFS data after autobk() results (see Note 1)
386 emin min energy to show, absolute or relative to E0 [-25]
387 emax max energy to show, absolute or relative to E0 [None, end of data]
388 label string for label [``None``: 'mu']
389 title string for plot title [None, may use filename if available]
390 new bool whether to start a new plot [True]
391 eweight energy weightingn for energisdef es>e0 [0]
392 show_k bool whether to show k values [True]
393 delay_draw bool whether to delay draw until more traces are added [False]
394 offset vertical offset to use for y-array [0]
395 win integer plot window to use [1]
397 Notes
398 -----
399 1. The input data group must have the following attributes:
400 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
401 """
402 if hasattr(dgroup, 'mu'):
403 mu = dgroup.mu
404 elif hasattr(dgroup, 'mutrans'):
405 mu = dgroup.mutrans
406 else:
407 raise ValueError("XAFS data group has no array for mu")
408 #endif
409 e0 = dgroup.e0
410 chie = (mu - dgroup.bkg)
411 ylabel = plotlabels.chie
412 if abs(eweight) > 1.e-2:
413 chie *= (dgroup.energy-e0)**(eweight)
414 ylabel = plotlabels.chiew.format(eweight)
416 xlabel = plotlabels.ewithk if show_k else plotlabels.energy
418 emin, emax = _get_erange(dgroup, emin, emax)
419 if emin is not None:
420 emin = emin - e0
421 if emax is not None:
422 emax = emax - e0
425 title = _get_title(dgroup, title=title)
427 def ek_formatter(x, pos):
428 ex = float(x)
429 if ex < 0:
430 s = ''
431 else:
432 s = '\n[%.2f]' % (etok(ex))
433 return r"%1.4g%s" % (x, s)
435 _plot(dgroup.energy-e0, chie+offset, xlabel=xlabel, ylabel=ylabel,
436 title=title, label=label, zorder=20, new=new, xmin=emin,
437 xmax=emax, win=win, show_legend=True, delay_draw=delay_draw,
438 linewidth=3, _larch=_larch)
440 if show_k:
441 disp = get_display(win=win, _larch=_larch)
442 axes = disp.panel.axes
443 axes.xaxis.set_major_formatter(FuncFormatter(ek_formatter))
445 if not delay_draw:
446 redraw(win=win, xmin=emin, xmax=emax, _larch=_larch)
448#enddef
450def plot_chik(dgroup, kweight=None, kmax=None, show_window=True,
451 scale_window=True, label=None, title=None, new=True,
452 delay_draw=False, offset=0, win=1, _larch=None):
453 """
454 plot_chik(dgroup, kweight=None, kmax=None, show_window=True, label=None,
455 new=True, win=1)
457 Plot k-weighted chi(k) for XAFS data group
459 Arguments
460 ----------
461 dgroup group of XAFS data after autobk() results (see Note 1)
462 kweight k-weighting for plot [read from last xftf(), or 0]
463 kmax max k to show [None, end of data]
464 show_window bool whether to also plot k-window [True]
465 scale_window bool whether to scale k-window to max |chi(k)| [True]
466 label string for label [``None`` to use 'chi']
467 title string for plot title [None, may use filename if available]
468 new bool whether to start a new plot [True]
469 delay_draw bool whether to delay draw until more traces are added [False]
470 offset vertical offset to use for y-array [0]
471 win integer plot window to use [1]
473 Notes
474 -----
475 1. The input data group must have the following attributes:
476 k, chi, kwin, filename
477 """
478 kweight = _get_kweight(dgroup, kweight)
480 chi = dgroup.chi * dgroup.k ** kweight
481 opts = dict(win=win, show_legend=True, delay_draw=True, linewidth=3,
482 _larch=_larch)
483 if label is None:
484 label = 'chi'
485 #endif
486 if new:
487 title = _get_title(dgroup, title=title)
488 _plot(dgroup.k, chi+offset, xlabel=plotlabels.k,
489 ylabel=plotlabels.chikw.format(kweight), title=title,
490 label=label, zorder=20, new=new, xmax=kmax, **opts)
492 if show_window and hasattr(dgroup, 'kwin'):
493 kwin = dgroup.kwin
494 if scale_window:
495 kwin = kwin*max(abs(chi))
496 _plot(dgroup.k, kwin+offset, zorder=12, label='window', **opts)
497 #endif
498 redraw(win=win, xmax=kmax, _larch=_larch)
499#enddef
501def plot_chir(dgroup, show_mag=True, show_real=False, show_imag=False,
502 show_window=False, rmax=None, label=None, title=None,
503 new=True, delay_draw=False, offset=0, win=1, _larch=None):
504 """
505 plot_chir(dgroup, show_mag=True, show_real=False, show_imag=False,
506 rmax=None, label=None, new=True, win=1)
508 Plot chi(R) for XAFS data group
510 Arguments
511 ----------
512 dgroup group of XAFS data after xftf() results (see Note 1)
513 show_mag bool whether to plot |chi(R)| [True]
514 show_real bool whether to plot Re[chi(R)] [False]
515 show_imag bool whether to plot Im[chi(R)] [False]
516 show_window bool whether to R-windw for back FT (will be scaled) [False]
517 label string for label [``None`` to use 'chir']
518 title string for plot title [None, may use filename if available]
519 rmax max R to show [None, end of data]
520 new bool whether to start a new plot [True]
521 delay_draw bool whether to delay draw until more traces are added [False]
522 offset vertical offset to use for y-array [0]
523 win integer plot window to use [1]
525 Notes
526 -----
527 1. The input data group must have the following attributes:
528 r, chir_mag, chir_im, chir_re, kweight, filename
529 """
530 kweight = _get_kweight(dgroup, None)
532 if new:
533 title = _get_title(dgroup, title=title)
535 opts = dict(win=win, show_legend=True, linewidth=3, title=title,
536 zorder=20, xmax=rmax, xlabel=plotlabels.r, new=new,
537 delay_draw=True, _larch=_larch)
539 ylabel = plotlabels.chirlab(kweight, show_mag=show_mag,
540 show_real=show_real, show_imag=show_imag)
541 opts['ylabel'] = ylabel
542 if not hasattr(dgroup, 'r'):
543 print("group does not have chi(R) data")
544 return
545 #endif
546 if label is None:
547 label = 'chir'
548 #endif
549 if show_mag:
550 _plot(dgroup.r, dgroup.chir_mag+offset, label='%s (mag)' % label, **opts)
551 opts['new'] = False
552 #endif
553 if show_real:
554 _plot(dgroup.r, dgroup.chir_re+offset, label='%s (real)' % label, **opts)
555 opts['new'] = False
556 #endif
557 if show_imag:
558 _plot(dgroup.r, dgroup.chir_im+offset, label='%s (imag)' % label, **opts)
559 #endif
560 if show_window and hasattr(dgroup, 'rwin'):
561 rwin = dgroup.rwin * max(dgroup.chir_mag)
562 opts['zorder'] = 15
563 _plot(dgroup.r, rwin+offset, label='window', **opts)
564 #endif
566 if show_mag or show_real or show_imag or show_window:
567 redraw(win=win, xmax=rmax, _larch=_larch)
568 #endif
569#enddef
571def plot_chiq(dgroup, kweight=None, kmax=None, show_chik=False, label=None,
572 title=None, new=True, delay_draw=False, offset=0, win=1,
573 show_window=False, scale_window=True, _larch=None):
574 """
575 plot_chiq(dgroup, kweight=None, kmax=None, show_chik=False, label=None,
576 new=True, win=1)
578 Plot Fourier filtered chi(k), optionally with k-weighted chi(k) for XAFS data group
580 Arguments
581 ----------
582 dgroup group of XAFS data after autobk() results (see Note 1)
583 kweight k-weighting for plot [read from last xftf(), or 0]
584 kmax max k to show [None, end of data]
585 show_chik bool whether to also plot k-weighted chi(k) [False]
586 show_window bool whether to also plot FT k-window [False]
587 scale_window bool whether to scale FT k-window to max |chi(q)| [True]
588 label string for label [``None`` to use 'chi']
589 title string for plot title [None, may use filename if available]
590 new bool whether to start a new plot [True]
591 delay_draw bool whether to delay draw until more traces are added [False]
592 offset vertical offset to use for y-array [0]
593 win integer plot window to use [1]
595 Notes
596 -----
597 1. The input data group must have the following attributes:
598 k, chi, kwin, filename
599 """
600 kweight = _get_kweight(dgroup, kweight)
601 nk = len(dgroup.k)
602 chiq = dgroup.chiq_re[:nk]
603 opts = dict(win=win, show_legend=True, delay_draw=True, linewidth=3, _larch=_larch)
604 if label is None:
605 label = 'chi(q) (filtered)'
606 #endif
607 if new:
608 title = _get_title(dgroup, title=title)
610 _plot(dgroup.k, chiq+offset, xlabel=plotlabels.k,
611 ylabel=plotlabels.chikw.format(kweight), title=title,
612 label=label, zorder=20, new=new, xmax=kmax, **opts)
614 if show_chik:
615 chik = dgroup.chi * dgroup.k ** kweight
616 _plot(dgroup.k, chik+offset, zorder=16, label='chi(k)', **opts)
617 #endif
618 if show_window and hasattr(dgroup, 'kwin'):
619 kwin = dgroup.kwin
620 if scale_window:
621 kwin = kwin*max(abs(chiq))
622 _plot(dgroup.k, kwin+offset, zorder=12, label='window', **opts)
623 #endif
625 redraw(win=win, xmax=kmax, _larch=_larch)
626#enddef
629def plot_wavelet(dgroup, show_mag=True, show_real=False, show_imag=False,
630 rmax=None, kmax=None, kweight=None, title=None, win=1, _larch=None):
631 """
632 plot_wavelet(dgroup, show_mag=True, show_real=False, show_imag=False,
633 rmax=None, kmax=None, kweight=None, title=None, win=1)
635 Plot wavelet for XAFS data group
637 Arguments
638 ----------
639 dgroup group of XAFS data after xftf() results (see Note 1)
640 show_mag bool whether to plot wavelet magnitude [True]
641 show_real bool whether to plot real part of wavelet [False]
642 show_imag bool whether to plot imaginary part of wavelet [False]
643 title string for plot title [None, may use filename if available]
644 rmax max R to show [None, end of data]
645 kmax max k to show [None, end of data]
646 kweight k-weight to use to construct wavelet [None, take from group]
647 win integer image window to use [1]
649 Notes
650 -----
651 The wavelet will be performed
652 """
653 kweight = _get_kweight(dgroup, kweight)
654 cauchy_wavelet(dgroup, kweight=kweight, rmax_out=rmax)
655 title = _get_title(dgroup, title=title)
657 opts = dict(win=win, title=title, x=dgroup.k, y=dgroup.wcauchy_r, xmax=kmax,
658 ymax=rmax, xlabel=plotlabels.k, ylabel=plotlabels.r,
659 show_axis=True, _larch=_larch)
660 if show_mag:
661 _imshow(dgroup.wcauchy_mag, **opts)
662 elif show_real:
663 _imshow(dgroup.wcauchy_real, **opts)
664 elif show_imag:
665 _imshow(dgroup.wcauchy_imag, **opts)
666 #endif
667#enddef
669def plot_chifit(dataset, kmin=0, kmax=None, kweight=None, rmax=None,
670 show_mag=True, show_real=False, show_imag=False,
671 show_bkg=False, use_rebkg=False, title=None, new=True,
672 delay_draw=False, offset=0, win=1, _larch=None):
674 """
675 plot_chifit(dataset, kmin=0, kmax=None, rmax=None,
676 show_mag=True, show_real=False, show_imag=False,
677 new=True, win=1)
679 Plot k-weighted chi(k) and chi(R) for fit to feffit dataset
681 Arguments
682 ----------
683 dataset feffit dataset, after running feffit()
684 kmin min k to show [0]
685 kmax max k to show [None, end of data]
686 kweight kweight to show [None, taken from dataset]
687 rmax max R to show [None, end of data]
688 show_mag bool whether to plot |chidr(R)| [True]
689 show_real bool whether to plot Re[chi(R)] [False]
690 show_imag bool whether to plot Im[chi(R)] [False]
691 show_bkg bool whether to plot feffit-refined background [False]
692 use_rebkg bool whether to plot data with feffit-refined background [False]
693 title string for plot title [None, may use filename if available]
694 new bool whether to start a new plot [True]
695 delay_draw bool whether to delay draw until more traces are added [False]
696 offset vertical offset to use for y-array [0]
697 win integer plot window to use [1]
699 """
700 if kweight is None:
701 kweight = dataset.transform.kweight
702 #endif
703 if isinstance(kweight, (list, tuple, ndarray)):
704 kweight=kweight[0]
706 title = _get_title(dataset, title=title)
708 mod = dataset.model
709 dat = dataset.data
710 if use_rebkg and hasattr(dataset, 'data_rebkg'):
711 dat = dataset.data_rebkg
712 title += ' (refined bkg)'
714 data_chik = dat.chi * dat.k**kweight
715 model_chik = mod.chi * mod.k**kweight
717 opts=dict(labelfontsize=10, legendfontsize=10, linewidth=3,
718 show_legend=True, delay_draw=True, win=win, title=title,
719 _larch=_larch)
721 # k-weighted chi(k) in first plot window
722 _plot(dat.k, data_chik+offset, xmin=kmin, xmax=kmax,
723 xlabel=plotlabels.k, ylabel=plotlabels.chikw.format(kweight),
724 label='data', new=new, **opts)
725 _plot(mod.k, model_chik+offset, label='fit', **opts)
727 if show_bkg and hasattr(dat, 'bkgk'):
728 _plot(dat.k, dat.bkgk*dat.k**kweight,
729 label='refined bkg', **opts)
730 #endif
732 redraw(win=win, xmin=kmin, xmax=kmax, _larch=_larch)
734 # show chi(R) in next plot window
735 opts['win'] = win = win+1
736 ylabel = plotlabels.chirlab(kweight, show_mag=show_mag,
737 show_real=show_real, show_imag=show_imag)
739 opts.update(dict(xlabel=plotlabels.r, ylabel=ylabel,
740 xmax=rmax, new=True, show_legend=True))
742 if show_mag:
743 _plot(dat.r, dat.chir_mag+offset, label='|data|', **opts)
744 opts['new'] = False
745 _plot(mod.r, mod.chir_mag+offset, label='|fit|', **opts)
746 #endif
747 if show_real:
748 _plot(dat.r, dat.chir_re+offset, label='Re[data]', **opts)
749 opts['new'] = False
750 _plot(mod.r, mod.chir_re+offset, label='Re[fit]', **opts)
751 #endif
752 if show_imag:
753 _plot(dat.r, dat.chir_im+offset, label='Im[data]', **opts)
754 opts['new'] = False
755 _plot(mod.r, mod.chir_im+offset, label='Im[fit]', **opts)
756 #endif
757 if show_mag or show_real or show_imag:
758 redraw(win=opts['win'], xmax=opts['xmax'], _larch=_larch)
759 #endif
760#enddef
762def plot_path_k(dataset, ipath=0, kmin=0, kmax=None, offset=0, label=None,
763 new=False, delay_draw=False, win=1, _larch=None, **kws):
764 """
765 plot_path_k(dataset, ipath, kmin=0, kmax=None, offset=0,
766 label=None, new=False, win=1, **kws)
768 Plot k-weighted chi(k) for a single Path of a feffit dataset
770 Arguments
771 ----------
772 dataset feffit dataset, after running feffit()
773 ipath index of path, starting count at 0 [0]
774 kmin min k to show [0]
775 kmax max k to show [None, end of data]
776 offset vertical offset to use for plot [0]
777 label path label ['path %d' % ipath]
778 new bool whether to start a new plot [True]
779 delay_draw bool whether to delay draw until more traces are added [False]
780 win integer plot window to use [1]
781 kws additional keyword arguments are passed to plot()
782 """
783 kweight = dataset.transform.kweight
784 path = dataset.pathlist[ipath]
785 if label is None: label = 'path %i' % (1+ipath)
787 chi_kw = offset + path.chi * path.k**kweight
789 _plot(path.k, chi_kw, label=label, xmin=kmin, xmax=kmax,
790 xlabel=plotlabels.k, ylabel=plotlabels.chikw.format(kweight),
791 win=win, new=new, delay_draw=delay_draw, _larch=_larch, **kws)
792 if delay_draw:
793 redraw(win=win, xmin=kmin, xmax=kmax, _larch=_larch)
794#enddef
796def plot_path_r(dataset, ipath, rmax=None, offset=0, label=None,
797 show_mag=True, show_real=False, show_imag=True,
798 new=False, delay_draw=False, win=1, _larch=None,
799 **kws):
800 """
801 plot_path_r(dataset, ipath,rmax=None, offset=0, label=None,
802 show_mag=True, show_real=False, show_imag=True,
803 new=False, win=1, **kws)
805 Plot chi(R) for a single Path of a feffit dataset
807 Arguments
808 ----------
809 dataset feffit dataset, after running feffit()
810 ipath index of path, starting count at 0 [0]
811 rmax max R to show [None, end of data]
812 offset vertical offset to use for plot [0]
813 label path label ['path %d' % ipath]
814 show_mag bool whether to plot |chi(R)| [True]
815 show_real bool whether to plot Re[chi(R)] [False]
816 show_imag bool whether to plot Im[chi(R)] [False]
817 new bool whether to start a new plot [True]
818 delay_draw bool whether to delay draw until more traces are added [False]
819 win integer plot window to use [1]
820 kws additional keyword arguments are passed to plot()
821 """
822 path = dataset.pathlist[ipath]
823 if label is None:
824 label = 'path %i' % (1+ipath)
825 #endif
826 kweight =dataset.transform.kweight
827 ylabel = plotlabels.chirlab(kweight, show_mag=show_mag,
828 show_real=show_real, show_imag=show_imag)
830 opts = dict(xlabel=plotlabels.r, ylabel=ylabel, xmax=rmax, new=new,
831 delay_draw=True, _larch=_larch)
833 opts.update(kws)
834 if show_mag:
835 _plot(path.r, offset+path.chir_mag, label=label, **opts)
836 opts['new'] = False
837 #endif
838 if show_real:
839 _plot(path.r, offset+path.chir_re, label=label, **opts)
840 opts['new'] = False
841 #endif
842 if show_imag:
843 _plot(path.r, offset+path.chir_im, label=label, **opts)
844 opts['new'] = False
845 #endif
846 redraw(win=win, xmax=rmax, _larch=_larch)
847#enddef
849def plot_paths_k(dataset, offset=-1, kmin=0, kmax=None, title=None,
850 new=True, delay_draw=False, win=1, _larch=None, **kws):
852 """
853 plot_paths_k(dataset, offset=-1, kmin=0, kmax=None, new=True, win=1, **kws):
855 Plot k-weighted chi(k) for model and all paths of a feffit dataset
857 Arguments
858 ----------
859 dataset feffit dataset, after running feffit()
860 kmin min k to show [0]
861 kmax max k to show [None, end of data]
862 offset vertical offset to use for paths for plot [-1]
863 new bool whether to start a new plot [True]
864 title string for plot title [None, may use filename if available]
865 win integer plot window to use [1]
866 delay_draw bool whether to delay draw until more traces are added [False]
867 kws additional keyword arguments are passed to plot()
868 """
869 # make k-weighted chi(k)
870 kweight = dataset.transform.kweight
871 model = dataset.model
873 model_chi_kw = model.chi * model.k**kweight
875 title = _get_title(dataset, title=title)
877 _plot(model.k, model_chi_kw, title=title, label='sum', new=new,
878 xlabel=plotlabels.r, ylabel=plotlabels.chikw.format(kweight),
879 xmin=kmin, xmax=kmax, win=win, delay_draw=True,_larch=_larch,
880 **kws)
882 for ipath in range(len(dataset.pathlist)):
883 plot_path_k(dataset, ipath, offset=(ipath+1)*offset,
884 kmin=kmin, kmax=kmax, new=False, delay_draw=True,
885 win=win, _larch=_larch)
886 #endfor
887 redraw(win=win, xmin=kmin, xmax=kmax, _larch=_larch)
888#enddef
890def plot_paths_r(dataset, offset=-0.25, rmax=None, show_mag=True,
891 show_real=False, show_imag=False, title=None, new=True,
892 win=1, delay_draw=False, _larch=None, **kws):
893 """
894 plot_paths_r(dataset, offset=-0.5, rmax=None, show_mag=True, show_real=False,
895 show_imag=False, new=True, win=1, **kws):
897 Plot chi(R) for model and all paths of a feffit dataset
899 Arguments
900 ----------
901 dataset feffit dataset, after running feffit()
902 offset vertical offset to use for paths for plot [-0.5]
903 rmax max R to show [None, end of data]
904 show_mag bool whether to plot |chi(R)| [True]
905 show_real bool whether to plot Re[chi(R)] [False]
906 show_imag bool whether to plot Im[chi(R)] [False]
907 title string for plot title [None, may use filename if available]
908 new bool whether to start a new plot [True]
909 delay_draw bool whether to delay draw until more traces are added [False]
910 win integer plot window to use [1]
911 kws additional keyword arguments are passed to plot()
912 """
913 kweight = dataset.transform.kweight
914 model = dataset.model
916 ylabel = plotlabels.chirlab(kweight, show_mag=show_mag,
917 show_real=show_real, show_imag=show_imag)
918 title = _get_title(dataset, title=title)
919 opts = dict(xlabel=plotlabels.r, ylabel=ylabel, xmax=rmax, new=new,
920 delay_draw=True, title=title, _larch=_larch)
921 opts.update(kws)
922 if show_mag:
923 _plot(model.r, model.chir_mag, label='|sum|', **opts)
924 opts['new'] = False
925 #endif
926 if show_real:
927 _plot(model.r, model.chir_re, label='Re[sum]', **opts)
928 opts['new'] = False
929 #endif
930 if show_imag:
931 _plot(model.r, model.chir_im, label='Im[sum]', **opts)
932 opts['new'] = False
933 #endif
935 for ipath in range(len(dataset.pathlist)):
936 plot_path_r(dataset, ipath, offset=(ipath+1)*offset,
937 show_mag=show_mag, show_real=show_real,
938 show_imag=show_imag, **opts)
939 #endfor
940 redraw(win=win, xmax=rmax,_larch=_larch)
941#enddef
944def extend_plotrange(x, y, xmin=None, xmax=None, extend=0.10):
945 """return plot limits to extend a plot range for x, y pairs"""
946 xeps = min(diff(x)) / 5.
947 if xmin is None:
948 xmin = min(x)
949 if xmax is None:
950 xmax = max(x)
952 xmin = max(min(x), xmin-5)
953 xmax = min(max(x), xmax+5)
955 i0 = index_of(x, xmin + xeps)
956 i1 = index_of(x, xmax + xeps) + 1
958 xspan = x[i0:i1]
959 xrange = max(xspan) - min(xspan)
960 yspan = y[i0:i1]
961 yrange = max(yspan) - min(yspan)
963 return (min(xspan) - extend * xrange,
964 max(xspan) + extend * xrange,
965 min(yspan) - extend * yrange,
966 max(yspan) + extend * yrange)
968def plot_prepeaks_baseline(dgroup, subtract_baseline=False, show_fitrange=True,
969 show_peakrange=True, win=1, _larch=None, **kws):
970 """Plot pre-edge peak baseline fit, as from `pre_edge_baseline` or XAS Viewer
972 dgroup must have a 'prepeaks' attribute
973 """
974 if not hasattr(dgroup, 'prepeaks'):
975 raise ValueError('Group needs prepeaks')
976 #endif
977 ppeak = dgroup.prepeaks
979 yplot = getattr(dgroup, 'yplot', getattr(dgroup, 'ydat', None))
980 xplot = getattr(dgroup, 'xplot', getattr(dgroup, 'x', None))
982 px0, px1, py0, py1 = extend_plotrange(xplot, yplot,
983 xmin=ppeak.emin, xmax=ppeak.emax)
985 title = "pre_edge baseline\n %s" % dgroup.filename
987 popts = dict(xmin=px0, xmax=px1, ymin=py0, ymax=py1, title=title,
988 xlabel='Energy (eV)', ylabel='mu (normalized)', delay_draw=True,
989 show_legend=True, style='solid', linewidth=3,
990 label='data', new=True,
991 marker='None', markersize=4, win=win, _larch=_larch)
992 popts.update(kws)
994 if subtract_baseline:
995 xplot = ppeak.energy
996 yplot = ppeak.baseline
997 popts['label'] = 'baseline subtracted peaks'
998 _plot(xplot, yplot, **popts)
999 else:
1000 _plot(xplot, yplot, **popts)
1001 popts['new'] = False
1002 popts['label'] = 'baseline'
1003 _oplot(ppeak.energy, ppeak.baseline, **popts)
1005 popts = dict(win=win, _larch=_larch, delay_draw=True,
1006 label='_nolegend_')
1008 if show_fitrange:
1009 for x in (ppeak.emin, ppeak.emax):
1010 _plot_axvline(x, color='#DDDDCC', **popts)
1011 _plot_axvline(ppeak.centroid, color='#EECCCC', **popts)
1013 if show_peakrange:
1014 for x in (ppeak.elo, ppeak.ehi):
1015 y = yplot[index_of(xplot, x)]
1016 _plot_marker(x, y, color='#222255', marker='o', size=8, **popts)
1018 redraw(win=win, xmin=px0, xmax=px1, ymin=py0, ymax=py1,
1019 show_legend=True, _larch=_larch)
1020#enddef
1022def plot_prepeaks_fit(dgroup, nfit=0, show_init=False, subtract_baseline=False,
1023 show_residual=False, win=1, _larch=None):
1024 """plot pre-edge peak fit, as from XAS Viewer
1026 dgroup must have a 'peakfit_history' attribute
1027 """
1028 if not hasattr(dgroup, 'prepeaks'):
1029 raise ValueError('Group needs prepeaks')
1030 #endif
1031 if show_init:
1032 result = pkfit = dgroup.prepeaks
1033 else:
1034 hist = getattr(dgroup.prepeaks, 'fit_history', None)
1035 if nfit > len(hist):
1036 nfit = 0
1037 pkfit = hist[nfit]
1038 result = pkfit.result
1039 #endif
1041 if pkfit is None:
1042 raise ValueError('Group needs prepeaks.fit_history or init_fit')
1043 #endif
1045 opts = pkfit.user_options
1046 xeps = min(diff(dgroup.xplot)) / 5.
1047 xplot = 1.0*pkfit.energy
1048 yplot = 1.0*pkfit.norm
1050 xplot_full = 1.0*dgroup.xplot
1051 yplot_full = 1.0*dgroup.yplot
1053 if show_init:
1054 yfit = pkfit.init_fit
1055 ycomps = None # pkfit.init_ycomps
1056 ylabel = 'model'
1057 else:
1058 yfit = 1.0*result.best_fit
1059 ycomps = pkfit.ycomps
1060 ylabel = 'best fit'
1062 baseline = 0.*yplot
1063 if ycomps is not None:
1064 for label, ycomp in ycomps.items():
1065 if label in opts['bkg_components']:
1066 baseline += ycomp
1068 plotopts = dict(title='%s:\npre-edge peak' % dgroup.filename,
1069 xlabel='Energy (eV)', ylabel=opts['array_desc'],
1070 delay_draw=True, show_legend=True, style='solid',
1071 linewidth=3, marker='None', markersize=4)
1073 if subtract_baseline:
1074 yplot -= baseline
1075 yfit -= baseline
1076 yplot_full = 1.0*yplot
1077 xplot_full = 1.0*xplot
1078 plotopts['ylabel'] = '%s-baseline' % plotopts['ylabel']
1080 dx0, dx1, dy0, dy1 = extend_plotrange(xplot_full, yplot_full,
1081 xmin=opts['emin'], xmax=opts['emax'])
1082 fx0, fx1, fy0, fy1 = extend_plotrange(xplot, yfit,
1083 xmin=opts['emin'], xmax=opts['emax'])
1085 ncolor = 0
1086 popts = {'win': win, '_larch': _larch}
1087 plotopts.update(popts)
1088 dymin = dymax = None
1089 if show_residual:
1090 popts['stacked'] = True
1091 _fitplot(xplot, yplot, yfit, label='data', label2=ylabel, **plotopts)
1092 dy = yfit - yplot
1093 dymax, dymin = dy.max(), dy.min()
1094 dymax += 0.05 * (dymax - dymin)
1095 dymin -= 0.05 * (dymax - dymin)
1096 else:
1097 _plot(xplot_full, yplot_full, new=True, label='data',
1098 color=LineColors[0], **plotopts)
1099 _oplot(xplot, yfit, label=ylabel, color=LineColors[1], **plotopts)
1100 ncolor = 1
1102 if ycomps is not None:
1103 ncomps = len(ycomps)
1104 if not subtract_baseline:
1105 ncolor += 1
1106 _oplot(xplot, baseline, label='baseline', delay_draw=True,
1107 style='short dashed', marker='None', markersize=5,
1108 color=LineColors[ncolor], **popts)
1110 for icomp, label in enumerate(ycomps):
1111 ycomp = ycomps[label]
1112 if label in opts['bkg_components']:
1113 continue
1114 ncolor = (ncolor+1) % 10
1115 _oplot(xplot, ycomp, label=label, delay_draw=(icomp != ncomps-1),
1116 style='short dashed', marker='None', markersize=5,
1117 color=LineColors[ncolor], **popts)
1119 if opts.get('show_fitrange', False):
1120 for attr in ('emin', 'emax'):
1121 _plot_axvline(opts[attr], ymin=0, ymax=1,
1122 delay_draw=False, color='#DDDDCC',
1123 label='_nolegend_', **popts)
1125 if opts.get('show_centroid', False):
1126 pcen = getattr(dgroup.prepeaks, 'centroid', None)
1127 if hasattr(result, 'params'):
1128 pcen = result.params.get('fit_centroid', None)
1129 if pcen is not None:
1130 pcen = pcen.value
1131 if pcen is not None:
1132 _plot_axvline(pcen, delay_draw=False, ymin=0, ymax=1,
1133 color='#EECCCC', label='_nolegend_', **popts)
1135 redraw(xmin=dx0, xmax=dx1, ymin=min(dy0, fy0),
1136 ymax=max(dy1, fy1), dymin=dymin, dymax=dymax, show_legend=True, **popts)
1138def _pca_ncomps(result, min_weight=0, ncomps=None):
1139 if ncomps is None:
1140 if min_weight > 1.e-12:
1141 ncomps = where(result.variances < min_weight)[0][0]
1142 else:
1143 ncomps = argmin(result.ind)
1144 return ncomps
1147def plot_pca_components(result, min_weight=0, ncomps=None, min_variance=1.e-5, win=1, _larch=None, **kws):
1148 """Plot components from PCA result
1150 result must be output of `pca_train`
1151 """
1152 title = "PCA components"
1153 popts = dict(xmin=result.xmin, xmax=result.xmax, title=title,
1154 xlabel=plotlabels.energy, ylabel=plotlabels.norm,
1155 delay_draw=True, show_legend=True, style='solid',
1156 linewidth=3, new=True, marker='None', markersize=4,
1157 win=win, _larch=_larch)
1159 popts.update(kws)
1160 ncomps = int(result.nsig)
1162 _plot(result.x, result.mean, label='Mean', **popts)
1163 for i, comp in enumerate(result.components):
1164 if result.variances[i] > min_variance:
1165 label = 'Comp# %d (%.4f)' % (i+1, result.variances[i])
1166 _oplot(result.x, comp, label=label, **popts)
1168 redraw(win=win, show_legend=True, _larch=_larch)
1170def plot_pca_weights(result, min_weight=0, ncomps=None, win=1, _larch=None, **kws):
1171 """Plot component weights from PCA result (aka SCREE plot)
1173 result must be output of `pca_train`
1174 """
1175 max_comps = len(result.components)
1177 title = "PCA Variances (SCREE) and Indicator Values"
1179 popts = dict(title=title, xlabel='Component #', zorder=10,
1180 xmax=max_comps+1.5, xmin=0.25, ymax=1, ylabel='variance',
1181 style='solid', ylog_scale=True, show_legend=True,
1182 linewidth=1, new=True, marker='o', win=win, _larch=_larch)
1184 popts.update(kws)
1186 ncomps = max(1, int(result.nsig))
1187 x = 1 + arange(ncomps)
1188 y = result.variances[:ncomps]
1189 _plot(x, y, label='significant', **popts)
1191 xe = 1 + arange(ncomps-1, max_comps)
1192 ye = result.variances[ncomps-1:ncomps+max_comps]
1194 popts.update(dict(new=False, zorder=5, style='short dashed',
1195 color='#B34050', ymin=2e-3*result.variances[ncomps-1]))
1196 _plot(xe, ye, label='not significant', **popts)
1198 xi = 1 + arange(len(result.ind)-1)
1200 _plot(xi, result.ind[1:], zorder=15, y2label='Indicator Value',
1201 label='IND', style='solid', win=win, show_legend=True,
1202 linewidth=1, marker='o', side='right', _larch=_larch)
1206def plot_pca_fit(dgroup, win=1, with_components=False, _larch=None, **kws):
1207 """Plot data and fit result from pca_fit, which rom PCA result
1209 result must be output of `pca_fit`
1210 """
1212 title = "PCA fit: %s" % (dgroup.filename)
1213 result = dgroup.pca_result
1214 model = result.pca_model
1216 popts = dict(xmin=model.xmin, xmax=model.xmax, title=title,
1217 xlabel=plotlabels.energy, ylabel=plotlabels.norm,
1218 delay_draw=True, show_legend=True, style='solid',
1219 linewidth=3, new=True, marker='None', markersize=4,
1220 stacked=True, win=win, _larch=_larch)
1221 popts.update(kws)
1222 yplot = getattr(result, 'yplot', getattr(result, 'ydat', None))
1223 if yplot is None:
1224 raise ValueError('cannot find y data for PCA plot')
1226 _fitplot(result.x, yplot, result.yfit,
1227 label='data', label2='PCA fit', **popts)
1229 disp = get_display(win=win, stacked=True, _larch=_larch)
1230 if with_components and disp is not None:
1231 disp.panel.oplot(result.x, model.mean, label='mean')
1232 for n in range(len(result.weights)):
1233 cval = model.components[n]*result.weights[n]
1234 disp.panel.oplot(result.x, cval, label='Comp #%d' % (n+1))
1235 redraw(win=win, show_legend=True, stacked=True, _larch=_larch)
1237def plot_diffkk(dgroup, emin=None, emax=None, new=True, label=None,
1238 title=None, delay_draw=False, offset=0, win=1, _larch=None):
1239 """
1240 plot_diffkk(dgroup, norm=True, emin=None, emax=None, show_e0=False, label=None, new=True, win=1):
1242 Plot mu(E) and background mu0(E) for XAFS data group
1244 Arguments
1245 ----------
1246 dgroup group of XAFS data after autobk() results (see Note 1)
1247 norm bool whether to show normalized data [True]
1248 emin min energy to show, absolute or relative to E0 [None, start of data]
1249 emax max energy to show, absolute or relative to E0 [None, end of data]
1250 show_e0 bool whether to show E0 [False]
1251 label string for label [``None``: 'mu']
1252 title string for plot title [None, may use filename if available]
1253 new bool whether to start a new plot [True]
1254 delay_draw bool whether to delay draw until more traces are added [False]
1255 offset vertical offset to use for y-array [0]
1256 win integer plot window to use [1]
1258 Notes
1259 -----
1260 1. The input data group must have the following attributes:
1261 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
1262 """
1263 if hasattr(dgroup, 'f2'):
1264 f2 = dgroup.f2
1265 else:
1266 raise ValueError("Data group has no array for f2")
1267 #endif
1268 ylabel = r'$f \rm\,\, (e^{-})$ '
1269 emin, emax = _get_erange(dgroup, emin, emax)
1270 title = _get_title(dgroup, title=title)
1272 labels = {'f2': r"$f_2(E)$", 'fpp': r"$f''(E)$", 'fp': r"$f'(E)$", 'f1': r"$f_1(E)$"}
1274 opts = dict(win=win, show_legend=True, linewidth=3,
1275 delay_draw=True, _larch=_larch)
1277 _plot(dgroup.energy, f2, xlabel=plotlabels.energy, ylabel=ylabel,
1278 title=title, label=labels['f2'], zorder=20, new=new, xmin=emin, xmax=emax,
1279 **opts)
1280 zorder = 15
1281 for attr in ('fpp', 'f1', 'fp'):
1282 yval = getattr(dgroup, attr)
1283 if yval is not None:
1284 _plot(dgroup.energy, yval, zorder=zorder, label=labels[attr], **opts)
1285 zorder = zorder - 3
1287 redraw(win=win, xmin=emin, xmax=emax, _larch=_larch)
1288#enddef
1290def plot_feffdat(feffpath, with_phase=True, title=None,
1291 new=True, delay_draw=False, win=1, _larch=None):
1292 """
1293 plot_feffdat(feffpath, with_phase=True, title=None, new=True, win=1):
1295 Plot Feff's magnitude and phase as a function of k for a FeffPath
1297 Arguments
1298 ----------
1299 feffpath feff path as read by feffpath()
1300 with_pase whether to plot phase(k) as well as magnitude [True]
1301 title string for plot title [None, may use filename if available]
1302 new bool whether to start a new plot [True]
1303 delay_draw bool whether to delay draw until more traces are added [False]
1304 win integer plot window to use [1]
1306 Notes
1307 -----
1308 1. The input data group must have the following attributes:
1309 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
1310 """
1311 if hasattr(feffpath, '_feffdat'):
1312 fdat = feffpath._feffdat
1313 else:
1314 raise ValueError("must pass in a Feff path as from feffpath()")
1315 #endif
1317 _plot(fdat.k, fdat.mag_feff, xlabel=plotlabels.k,
1318 ylabel='|F(k)|', title=title, label='magnitude', zorder=20,
1319 new=new, win=win, show_legend=True,
1320 delay_draw=delay_draw, linewidth=3, _larch=_larch)
1322 if with_phase:
1323 _plot(fdat.k, fdat.pha_feff, xlabel=plotlabels.k,
1324 y2label='Phase(k)', title=title, label='phase', side='right',
1325 zorder=10, new=False, win=win, show_legend=True,
1326 delay_draw=delay_draw, linewidth=3, _larch=_larch)
1327 #endif
1329 if delay_draw:
1330 redraw(win=win, xmin=emin, xmax=emax, _larch=_larch)
1331#enddef