Coverage for /Users/Newville/Codes/xraylarch/larch/wxlib/xafsplots.py: 29%
541 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
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"""
21import os
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)
98def safetitle(t):
99 if "'" in t:
100 t = t.replace("'", "\\'")
101 return t
103def _get_title(dgroup, title=None):
104 """get best title for group"""
105 if title is not None:
106 return safetitle(title)
107 data_group = getattr(dgroup, 'data', None)
109 for attr in ('title', 'plot_title', 'filename', 'name', '__name__'):
110 t = getattr(dgroup, attr, None)
111 if t is not None:
112 if attr == 'filename':
113 folder, file = os.path.split(t)
114 if folder == '':
115 t = file
116 else:
117 top, folder = os.path.split(folder)
118 t = '/'.join((folder, file))
119 return safetitle(t)
120 if data_group is not None:
121 t = getattr(data_group, attr, None)
122 if t is not None:
123 return t
124 return safetitle(repr(dgroup))
127def _get_kweight(dgroup, kweight=None):
128 if kweight is not None:
129 return kweight
130 callargs = getattr(dgroup, 'callargs', None)
131 ftargs = getattr(callargs, 'xftf', {'kweight':0})
132 return ftargs['kweight']
135def _get_erange(dgroup, emin=None, emax=None):
136 """get absolute emin/emax for data range, allowing using
137 values relative to e0.
138 """
139 dat_emin, dat_emax = min(dgroup.energy)-100, max(dgroup.energy)+100
140 e0 = getattr(dgroup, 'e0', 0.0)
141 if emin is not None:
142 if not (emin > dat_emin and emin < dat_emax):
143 if emin+e0 > dat_emin and emin+e0 < dat_emax:
144 emin += e0
145 if emax is not None:
146 if not (emax > dat_emin and emax < dat_emax):
147 if emax+e0 > dat_emin and emax+e0 < dat_emax:
148 emax += e0
149 return emin, emax
150#enddef
152def redraw(win=1, xmin=None, xmax=None, ymin=None, ymax=None,
153 dymin=None, dymax=None,
154 show_legend=True, stacked=False, _larch=None):
155 disp = get_display(win=win, stacked=stacked, _larch=_larch)
156 if disp is None:
157 return
158 panel = disp.panel
159 panel.conf.show_legend = show_legend
160 if (xmin is not None or xmax is not None or
161 ymin is not None or ymax is not None):
162 panel.set_xylims((xmin, xmax, ymin, ymax))
163 if stacked:
164 disp.panel_bot.set_xylims((xmin, xmax, dymin, dymax))
166 panel.unzoom_all()
167 panel.reset_formats()
168 if stacked:
169 disp.panel_bot.unzoom_all()
170 disp.panel_bot.reset_formats()
171 if show_legend: # note: draw_legend *will* redraw the canvas
172 panel.conf.draw_legend()
173 else:
174 panel.canvas.draw()
175 if stacked:
176 disp.panel_bot.canvas.draw()
178 #endif
179#enddef
182def plot_mu(dgroup, show_norm=False, show_flat=False, show_deriv=False,
183 show_pre=False, show_post=False, show_e0=False, with_deriv=False,
184 emin=None, emax=None, label='mu', new=True, delay_draw=False,
185 offset=0, title=None, win=1, _larch=None):
186 """
187 plot_mu(dgroup, norm=False, deriv=False, show_pre=False, show_post=False,
188 show_e0=False, show_deriv=False, emin=None, emax=None, label=None,
189 new=True, win=1)
191 Plot mu(E) for an XAFS data group in various forms
193 Arguments
194 ----------
195 dgroup group of XAFS data after pre_edge() results (see Note 1)
196 show_norm bool whether to show normalized data [False]
197 show_flat bool whether to show flattened, normalized data [False]
198 show_deriv bool whether to show derivative of normalized data [False]
199 show_pre bool whether to show pre-edge curve [False]
200 show_post bool whether to show post-edge curve [False]
201 show_e0 bool whether to show E0 [False]
202 with_deriv bool whether to show deriv (dmu/de) together with mu [False]
203 emin min energy to show, absolute or relative to E0 [None, start of data]
204 emax max energy to show, absolute or relative to E0 [None, end of data]
205 label string for label [None: 'mu', `dmu/dE', or 'mu norm']
206 title string for plot title [None, may use filename if available]
207 new bool whether to start a new plot [True]
208 delay_draw bool whether to delay draw until more traces are added [False]
209 offset vertical offset to use for y-array [0]
210 win integer plot window to use [1]
212 Notes
213 -----
214 1. The input data group must have the following attributes:
215 energy, mu, norm, e0, pre_edge, edge_step
216 """
217 if hasattr(dgroup, 'mu'):
218 mu = dgroup.mu
219 elif hasattr(dgroup, 'mutrans'):
220 mu = dgroup.mutrans
221 elif hasattr(dgroup, 'mufluor'):
222 mu = dgroup.mufluor
223 else:
224 raise ValueError("XAFS data group has no array for mu")
225 #endif
226 ylabel = plotlabels.mu
227 if label is None:
228 label = getattr(dgroup, 'filename', 'mu')
229 #endif
230 if show_deriv:
231 mu = dgroup.dmude
232 ylabel = "%s (deriv)" % ylabel
233 dlabel = plotlabels.dmude
234 elif show_norm:
235 mu = dgroup.norm
236 ylabel = "%s (norm)" % ylabel
237 dlabel = plotlabels.norm
238 #endif
239 elif show_flat:
240 mu = dgroup.flat
241 ylabel = "%s (flat)" % ylabel
242 dlabel = plotlabels.flat
243 #endif
244 emin, emax = _get_erange(dgroup, emin, emax)
245 title = _get_title(dgroup, title=title)
247 opts = dict(win=win, show_legend=True, linewidth=3,
248 title=title, xmin=emin, xmax=emax,
249 delay_draw=True, _larch=_larch)
251 _plot(dgroup.energy, mu+offset, xlabel=plotlabels.energy, ylabel=ylabel,
252 label=label, zorder=20, new=new, **opts)
254 if with_deriv:
255 dmu = dgroup.dmude
256 _plot(dgroup.energy, dmu+offset, ylabel=plotlabels.dmude,
257 label='%s (deriv)' % label, zorder=18, side='right', **opts)
258 #endif
259 if (not show_norm and not show_deriv):
260 if show_pre:
261 _plot(dgroup.energy, dgroup.pre_edge+offset, label='pre_edge',
262 zorder=18, **opts)
263 #endif
264 if show_post:
265 _plot(dgroup.energy, dgroup.post_edge+offset, label='post_edge',
266 zorder=18, **opts)
267 if show_pre:
268 i = index_of(dgroup.energy, dgroup.e0)
269 ypre = dgroup.pre_edge[i]
270 ypost = dgroup.post_edge[i]
271 _plot_arrow(dgroup.e0, ypre, dgroup.e0+offset, ypost,
272 color=plotlabels.e0color, width=0.25,
273 head_width=0, zorder=3, win=win, _larch=_larch)
274 #endif
275 #endif
276 #endif
277 if show_e0:
278 _plot_axvline(dgroup.e0, zorder=2, size=3,
279 label='E0', color=plotlabels.e0color, win=win,
280 _larch=_larch)
281 disp = get_display(win=win, _larch=_larch)
282 if disp is not None:
283 disp.panel.conf.draw_legend()
284 redraw(win=win, xmin=emin, xmax=emax, _larch=_larch)
285#enddef
287def plot_bkg(dgroup, norm=True, emin=None, emax=None, show_e0=False,
288 label=None, title=None, new=True, delay_draw=False, offset=0,
289 win=1, _larch=None):
290 """
291 plot_bkg(dgroup, norm=True, emin=None, emax=None, show_e0=False, label=None, new=True, win=1):
293 Plot mu(E) and background mu0(E) for XAFS data group
295 Arguments
296 ----------
297 dgroup group of XAFS data after autobk() results (see Note 1)
298 norm bool whether to show normalized data [True]
299 emin min energy to show, absolute or relative to E0 [None, start of data]
300 emax max energy to show, absolute or relative to E0 [None, end of data]
301 show_e0 bool whether to show E0 [False]
302 label string for label [``None``: 'mu']
303 title string for plot titlte [None, may use filename if available]
304 new bool whether to start a new plot [True]
305 delay_draw bool whether to delay draw until more traces are added [False]
306 offset vertical offset to use for y-array [0]
307 win integer plot window to use [1]
309 Notes
310 -----
311 1. The input data group must have the following attributes:
312 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
313 """
314 if hasattr(dgroup, 'mu'):
315 mu = dgroup.mu
316 elif hasattr(dgroup, 'mutrans'):
317 mu = dgroup.mutrans
318 else:
319 raise ValueError("XAFS data group has no array for mu")
320 #endif
322 bkg = dgroup.bkg
323 ylabel = plotlabels.mu
324 if label is None:
325 label = 'mu'
326 #endif
327 emin, emax = _get_erange(dgroup, emin, emax)
328 if norm:
329 mu = dgroup.norm
330 bkg = (dgroup.bkg - dgroup.pre_edge) / dgroup.edge_step
331 ylabel = "%s (norm)" % ylabel
332 label = "%s (norm)" % label
333 #endif
334 title = _get_title(dgroup, title=title)
335 opts = dict(win=win, show_legend=True, linewidth=3,
336 delay_draw=True, _larch=_larch)
337 _plot(dgroup.energy, mu+offset, xlabel=plotlabels.energy, ylabel=ylabel,
338 title=title, label=label, zorder=20, new=new, xmin=emin, xmax=emax,
339 **opts)
340 ymin, ymax = None, None
341 disp = get_display(win=win, _larch=_larch)
342 if disp is not None:
343 xylims = disp.panel.get_viewlimits()
344 ymin, ymax = xylims[2], xylims[3]
345 _plot(dgroup.energy, bkg+offset, zorder=18, label='bkg', **opts)
347 if show_e0:
348 _plot_axvline(dgroup.e0, zorder=2, size=3, label='E0',
349 color=plotlabels.e0color, win=win, _larch=_larch)
350 if disp is not None:
351 disp.panel.conf.draw_legend()
352 #endif
353 redraw(win=win, xmin=emin, xmax=emax, ymin=ymin, ymax=ymax, _larch=_larch)
354#enddef
356def plot_chie(dgroup, emin=-5, emax=None, label=None, title=None,
357 eweight=0, show_k=True, new=True, delay_draw=False,
358 offset=0, win=1, _larch=None):
359 """
360 plot_chie(dgroup, emin=None, emax=None, label=None, new=True, win=1):
362 Plot chi(E) for XAFS data group
364 Arguments
365 ----------
366 dgroup group of XAFS data after autobk() results (see Note 1)
367 emin min energy to show, absolute or relative to E0 [-25]
368 emax max energy to show, absolute or relative to E0 [None, end of data]
369 label string for label [``None``: 'mu']
370 title string for plot title [None, may use filename if available]
371 new bool whether to start a new plot [True]
372 eweight energy weightingn for energisdef es>e0 [0]
373 show_k bool whether to show k values [True]
374 delay_draw bool whether to delay draw until more traces are added [False]
375 offset vertical offset to use for y-array [0]
376 win integer plot window to use [1]
378 Notes
379 -----
380 1. The input data group must have the following attributes:
381 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
382 """
383 if hasattr(dgroup, 'mu'):
384 mu = dgroup.mu
385 elif hasattr(dgroup, 'mutrans'):
386 mu = dgroup.mutrans
387 else:
388 raise ValueError("XAFS data group has no array for mu")
389 #endif
390 e0 = dgroup.e0
391 chie = (mu - dgroup.bkg)
392 ylabel = plotlabels.chie
393 if abs(eweight) > 1.e-2:
394 chie *= (dgroup.energy-e0)**(eweight)
395 ylabel = plotlabels.chiew.format(eweight)
397 xlabel = plotlabels.ewithk if show_k else plotlabels.energy
399 emin, emax = _get_erange(dgroup, emin, emax)
400 if emin is not None:
401 emin = emin - e0
402 if emax is not None:
403 emax = emax - e0
406 title = _get_title(dgroup, title=title)
408 def ek_formatter(x, pos):
409 ex = float(x)
410 if ex < 0:
411 s = ''
412 else:
413 s = '\n[%.2f]' % (etok(ex))
414 return r"%1.4g%s" % (x, s)
416 _plot(dgroup.energy-e0, chie+offset, xlabel=xlabel, ylabel=ylabel,
417 title=title, label=label, zorder=20, new=new, xmin=emin,
418 xmax=emax, win=win, show_legend=True, delay_draw=delay_draw,
419 linewidth=3, _larch=_larch)
421 if show_k:
422 disp = get_display(win=win, _larch=_larch)
423 axes = disp.panel.axes
424 axes.xaxis.set_major_formatter(FuncFormatter(ek_formatter))
426 if not delay_draw:
427 redraw(win=win, xmin=emin, xmax=emax, _larch=_larch)
429#enddef
431def plot_chik(dgroup, kweight=None, kmax=None, show_window=True,
432 scale_window=True, label=None, title=None, new=True,
433 delay_draw=False, offset=0, win=1, _larch=None):
434 """
435 plot_chik(dgroup, kweight=None, kmax=None, show_window=True, label=None,
436 new=True, win=1)
438 Plot k-weighted chi(k) for XAFS data group
440 Arguments
441 ----------
442 dgroup group of XAFS data after autobk() results (see Note 1)
443 kweight k-weighting for plot [read from last xftf(), or 0]
444 kmax max k to show [None, end of data]
445 show_window bool whether to also plot k-window [True]
446 scale_window bool whether to scale k-window to max |chi(k)| [True]
447 label string for label [``None`` to use 'chi']
448 title string for plot title [None, may use filename if available]
449 new bool whether to start a new plot [True]
450 delay_draw bool whether to delay draw until more traces are added [False]
451 offset vertical offset to use for y-array [0]
452 win integer plot window to use [1]
454 Notes
455 -----
456 1. The input data group must have the following attributes:
457 k, chi, kwin, filename
458 """
459 kweight = _get_kweight(dgroup, kweight)
461 chi = dgroup.chi * dgroup.k ** kweight
462 opts = dict(win=win, show_legend=True, delay_draw=True, linewidth=3,
463 _larch=_larch)
464 if label is None:
465 label = 'chi'
466 #endif
467 if new:
468 title = _get_title(dgroup, title=title)
469 _plot(dgroup.k, chi+offset, xlabel=plotlabels.k,
470 ylabel=plotlabels.chikw.format(kweight), title=title,
471 label=label, zorder=20, new=new, xmax=kmax, **opts)
473 if show_window and hasattr(dgroup, 'kwin'):
474 kwin = dgroup.kwin
475 if scale_window:
476 kwin = kwin*max(abs(chi))
477 _plot(dgroup.k, kwin+offset, zorder=12, label='window', **opts)
478 #endif
479 redraw(win=win, xmax=kmax, _larch=_larch)
480#enddef
482def plot_chir(dgroup, show_mag=True, show_real=False, show_imag=False,
483 show_window=False, rmax=None, label=None, title=None,
484 new=True, delay_draw=False, offset=0, win=1, _larch=None):
485 """
486 plot_chir(dgroup, show_mag=True, show_real=False, show_imag=False,
487 rmax=None, label=None, new=True, win=1)
489 Plot chi(R) for XAFS data group
491 Arguments
492 ----------
493 dgroup group of XAFS data after xftf() results (see Note 1)
494 show_mag bool whether to plot |chi(R)| [True]
495 show_real bool whether to plot Re[chi(R)] [False]
496 show_imag bool whether to plot Im[chi(R)] [False]
497 show_window bool whether to R-windw for back FT (will be scaled) [False]
498 label string for label [``None`` to use 'chir']
499 title string for plot title [None, may use filename if available]
500 rmax max R to show [None, end of data]
501 new bool whether to start a new plot [True]
502 delay_draw bool whether to delay draw until more traces are added [False]
503 offset vertical offset to use for y-array [0]
504 win integer plot window to use [1]
506 Notes
507 -----
508 1. The input data group must have the following attributes:
509 r, chir_mag, chir_im, chir_re, kweight, filename
510 """
511 kweight = _get_kweight(dgroup, None)
513 if new:
514 title = _get_title(dgroup, title=title)
516 opts = dict(win=win, show_legend=True, linewidth=3, title=title,
517 zorder=20, xmax=rmax, xlabel=plotlabels.r, new=new,
518 delay_draw=True, _larch=_larch)
520 ylabel = plotlabels.chirlab(kweight, show_mag=show_mag,
521 show_real=show_real, show_imag=show_imag)
522 opts['ylabel'] = ylabel
523 if not hasattr(dgroup, 'r'):
524 print("group does not have chi(R) data")
525 return
526 #endif
527 if label is None:
528 label = 'chir'
529 #endif
530 if show_mag:
531 _plot(dgroup.r, dgroup.chir_mag+offset, label='%s (mag)' % label, **opts)
532 opts['new'] = False
533 #endif
534 if show_real:
535 _plot(dgroup.r, dgroup.chir_re+offset, label='%s (real)' % label, **opts)
536 opts['new'] = False
537 #endif
538 if show_imag:
539 _plot(dgroup.r, dgroup.chir_im+offset, label='%s (imag)' % label, **opts)
540 #endif
541 if show_window and hasattr(dgroup, 'rwin'):
542 rwin = dgroup.rwin * max(dgroup.chir_mag)
543 opts['zorder'] = 15
544 _plot(dgroup.r, rwin+offset, label='window', **opts)
545 #endif
547 if show_mag or show_real or show_imag or show_window:
548 redraw(win=win, xmax=rmax, _larch=_larch)
549 #endif
550#enddef
552def plot_chiq(dgroup, kweight=None, kmax=None, show_chik=False, label=None,
553 title=None, new=True, delay_draw=False, offset=0, win=1,
554 show_window=False, scale_window=True, _larch=None):
555 """
556 plot_chiq(dgroup, kweight=None, kmax=None, show_chik=False, label=None,
557 new=True, win=1)
559 Plot Fourier filtered chi(k), optionally with k-weighted chi(k) for XAFS data group
561 Arguments
562 ----------
563 dgroup group of XAFS data after autobk() results (see Note 1)
564 kweight k-weighting for plot [read from last xftf(), or 0]
565 kmax max k to show [None, end of data]
566 show_chik bool whether to also plot k-weighted chi(k) [False]
567 show_window bool whether to also plot FT k-window [False]
568 scale_window bool whether to scale FT k-window to max |chi(q)| [True]
569 label string for label [``None`` to use 'chi']
570 title string for plot title [None, may use filename if available]
571 new bool whether to start a new plot [True]
572 delay_draw bool whether to delay draw until more traces are added [False]
573 offset vertical offset to use for y-array [0]
574 win integer plot window to use [1]
576 Notes
577 -----
578 1. The input data group must have the following attributes:
579 k, chi, kwin, filename
580 """
581 kweight = _get_kweight(dgroup, kweight)
582 nk = len(dgroup.k)
583 chiq = dgroup.chiq_re[:nk]
584 opts = dict(win=win, show_legend=True, delay_draw=True, linewidth=3, _larch=_larch)
585 if label is None:
586 label = 'chi(q) (filtered)'
587 #endif
588 if new:
589 title = _get_title(dgroup, title=title)
591 _plot(dgroup.k, chiq+offset, xlabel=plotlabels.k,
592 ylabel=plotlabels.chikw.format(kweight), title=title,
593 label=label, zorder=20, new=new, xmax=kmax, **opts)
595 if show_chik:
596 chik = dgroup.chi * dgroup.k ** kweight
597 _plot(dgroup.k, chik+offset, zorder=16, label='chi(k)', **opts)
598 #endif
599 if show_window and hasattr(dgroup, 'kwin'):
600 kwin = dgroup.kwin
601 if scale_window:
602 kwin = kwin*max(abs(chiq))
603 _plot(dgroup.k, kwin+offset, zorder=12, label='window', **opts)
604 #endif
606 redraw(win=win, xmax=kmax, _larch=_larch)
607#enddef
610def plot_wavelet(dgroup, show_mag=True, show_real=False, show_imag=False,
611 rmax=None, kmax=None, kweight=None, title=None, win=1, _larch=None):
612 """
613 plot_wavelet(dgroup, show_mag=True, show_real=False, show_imag=False,
614 rmax=None, kmax=None, kweight=None, title=None, win=1)
616 Plot wavelet for XAFS data group
618 Arguments
619 ----------
620 dgroup group of XAFS data after xftf() results (see Note 1)
621 show_mag bool whether to plot wavelet magnitude [True]
622 show_real bool whether to plot real part of wavelet [False]
623 show_imag bool whether to plot imaginary part of wavelet [False]
624 title string for plot title [None, may use filename if available]
625 rmax max R to show [None, end of data]
626 kmax max k to show [None, end of data]
627 kweight k-weight to use to construct wavelet [None, take from group]
628 win integer image window to use [1]
630 Notes
631 -----
632 The wavelet will be performed
633 """
634 kweight = _get_kweight(dgroup, kweight)
635 cauchy_wavelet(dgroup, kweight=kweight, rmax_out=rmax)
636 title = _get_title(dgroup, title=title)
638 opts = dict(win=win, title=title, x=dgroup.k, y=dgroup.wcauchy_r, xmax=kmax,
639 ymax=rmax, xlabel=plotlabels.k, ylabel=plotlabels.r,
640 show_axis=True, _larch=_larch)
641 if show_mag:
642 _imshow(dgroup.wcauchy_mag, **opts)
643 elif show_real:
644 _imshow(dgroup.wcauchy_real, **opts)
645 elif show_imag:
646 _imshow(dgroup.wcauchy_imag, **opts)
647 #endif
648#enddef
650def plot_chifit(dataset, kmin=0, kmax=None, kweight=None, rmax=None,
651 show_mag=True, show_real=False, show_imag=False,
652 title=None, new=True, delay_draw=False, offset=0, win=1,
653 _larch=None):
654 """
655 plot_chifit(dataset, kmin=0, kmax=None, rmax=None,
656 show_mag=True, show_real=False, show_imag=False,
657 new=True, win=1)
659 Plot k-weighted chi(k) and chi(R) for fit to feffit dataset
661 Arguments
662 ----------
663 dataset feffit dataset, after running feffit()
664 kmin min k to show [0]
665 kmax max k to show [None, end of data]
666 kweight kweight to show [None, taken from dataset]
667 rmax max R to show [None, end of data]
668 show_mag bool whether to plot |chidr(R)| [True]
669 show_real bool whether to plot Re[chi(R)] [False]
670 show_imag bool whether to plot Im[chi(R)] [False]
671 title string for plot title [None, may use filename if available]
672 new bool whether to start a new plot [True]
673 delay_draw bool whether to delay draw until more traces are added [False]
674 offset vertical offset to use for y-array [0]
675 win integer plot window to use [1]
677 """
678 if kweight is None:
679 kweight = dataset.transform.kweight
680 #endif
681 if isinstance(kweight, (list, tuple, ndarray)): kweight=kweight[0]
683 data_chik = dataset.data.chi * dataset.data.k**kweight
684 model_chik = dataset.model.chi * dataset.model.k**kweight
686 title = _get_title(dataset, title=title)
688 opts=dict(labelfontsize=10, legendfontsize=10, linewidth=3,
689 show_legend=True, delay_draw=True, win=win, title=title,
690 _larch=_larch)
692 # k-weighted chi(k) in first plot window
693 _plot(dataset.data.k, data_chik+offset, xmin=kmin, xmax=kmax,
694 xlabel=plotlabels.k, ylabel=plotlabels.chikw.format(kweight),
695 label='data', new=new, **opts)
696 _plot(dataset.model.k, model_chik+offset, label='fit', **opts)
697 redraw(win=win, xmin=kmin, xmax=kmax, _larch=_larch)
699 # show chi(R) in next plot window
700 opts['win'] = win = win+1
701 ylabel = plotlabels.chirlab(kweight, show_mag=show_mag,
702 show_real=show_real, show_imag=show_imag)
704 opts.update(dict(xlabel=plotlabels.r, ylabel=ylabel,
705 xmax=rmax, new=True, show_legend=True))
707 if show_mag:
708 _plot(dataset.data.r, dataset.data.chir_mag+offset,
709 label='|data|', **opts)
710 opts['new'] = False
711 _plot(dataset.model.r, dataset.model.chir_mag+offset,
712 label='|fit|', **opts)
713 #endif
714 if show_real:
715 _plot(dataset.data.r, dataset.data.chir_re+offset, label='Re[data]', **opts)
716 opts['new'] = False
717 _plot(dataset.model.r, dataset.model.chir_re+offset, label='Re[fit]', **opts)
718 #endif
719 if show_imag:
720 _plot(dataset.data.r, dataset.data.chir_im+offset, label='Im[data]', **opts)
721 opts['new'] = False
722 _plot(dataset.model.r, dataset.model.chir_im+offset, label='Im[fit]', **opts)
723 #endif
724 if show_mag or show_real or show_imag:
725 redraw(win=opts['win'], xmax=opts['xmax'], _larch=_larch)
726 #endif
727#enddef
729def plot_path_k(dataset, ipath=0, kmin=0, kmax=None, offset=0, label=None,
730 new=False, delay_draw=False, win=1, _larch=None, **kws):
731 """
732 plot_path_k(dataset, ipath, kmin=0, kmax=None, offset=0,
733 label=None, new=False, win=1, **kws)
735 Plot k-weighted chi(k) for a single Path of a feffit dataset
737 Arguments
738 ----------
739 dataset feffit dataset, after running feffit()
740 ipath index of path, starting count at 0 [0]
741 kmin min k to show [0]
742 kmax max k to show [None, end of data]
743 offset vertical offset to use for plot [0]
744 label path label ['path %d' % ipath]
745 new bool whether to start a new plot [True]
746 delay_draw bool whether to delay draw until more traces are added [False]
747 win integer plot window to use [1]
748 kws additional keyword arguments are passed to plot()
749 """
750 kweight = dataset.transform.kweight
751 path = dataset.pathlist[ipath]
752 if label is None: label = 'path %i' % (1+ipath)
754 chi_kw = offset + path.chi * path.k**kweight
756 _plot(path.k, chi_kw, label=label, xmin=kmin, xmax=kmax,
757 xlabel=plotlabels.k, ylabel=plotlabels.chikw.format(kweight),
758 win=win, new=new, delay_draw=delay_draw, _larch=_larch, **kws)
759 if delay_draw:
760 redraw(win=win, xmin=kmin, xmax=kmax, _larch=_larch)
761#enddef
763def plot_path_r(dataset, ipath, rmax=None, offset=0, label=None,
764 show_mag=True, show_real=False, show_imag=True,
765 new=False, delay_draw=False, win=1, _larch=None,
766 **kws):
767 """
768 plot_path_r(dataset, ipath,rmax=None, offset=0, label=None,
769 show_mag=True, show_real=False, show_imag=True,
770 new=False, win=1, **kws)
772 Plot chi(R) for a single Path of a feffit dataset
774 Arguments
775 ----------
776 dataset feffit dataset, after running feffit()
777 ipath index of path, starting count at 0 [0]
778 rmax max R to show [None, end of data]
779 offset vertical offset to use for plot [0]
780 label path label ['path %d' % ipath]
781 show_mag bool whether to plot |chi(R)| [True]
782 show_real bool whether to plot Re[chi(R)] [False]
783 show_imag bool whether to plot Im[chi(R)] [False]
784 new bool whether to start a new plot [True]
785 delay_draw bool whether to delay draw until more traces are added [False]
786 win integer plot window to use [1]
787 kws additional keyword arguments are passed to plot()
788 """
789 path = dataset.pathlist[ipath]
790 if label is None:
791 label = 'path %i' % (1+ipath)
792 #endif
793 kweight =dataset.transform.kweight
794 ylabel = plotlabels.chirlab(kweight, show_mag=show_mag,
795 show_real=show_real, show_imag=show_imag)
797 opts = dict(xlabel=plotlabels.r, ylabel=ylabel, xmax=rmax, new=new,
798 delay_draw=True, _larch=_larch)
800 opts.update(kws)
801 if show_mag:
802 _plot(path.r, offset+path.chir_mag, label=label, **opts)
803 opts['new'] = False
804 #endif
805 if show_real:
806 _plot(path.r, offset+path.chir_re, label=label, **opts)
807 opts['new'] = False
808 #endif
809 if show_imag:
810 _plot(path.r, offset+path.chir_im, label=label, **opts)
811 opts['new'] = False
812 #endif
813 redraw(win=win, xmax=rmax, _larch=_larch)
814#enddef
816def plot_paths_k(dataset, offset=-1, kmin=0, kmax=None, title=None,
817 new=True, delay_draw=False, win=1, _larch=None, **kws):
819 """
820 plot_paths_k(dataset, offset=-1, kmin=0, kmax=None, new=True, win=1, **kws):
822 Plot k-weighted chi(k) for model and all paths of a feffit dataset
824 Arguments
825 ----------
826 dataset feffit dataset, after running feffit()
827 kmin min k to show [0]
828 kmax max k to show [None, end of data]
829 offset vertical offset to use for paths for plot [-1]
830 new bool whether to start a new plot [True]
831 title string for plot title [None, may use filename if available]
832 win integer plot window to use [1]
833 delay_draw bool whether to delay draw until more traces are added [False]
834 kws additional keyword arguments are passed to plot()
835 """
836 # make k-weighted chi(k)
837 kweight = dataset.transform.kweight
838 model = dataset.model
840 model_chi_kw = model.chi * model.k**kweight
842 title = _get_title(dataset, title=title)
844 _plot(model.k, model_chi_kw, title=title, label='sum', new=new,
845 xlabel=plotlabels.r, ylabel=plotlabels.chikw.format(kweight),
846 xmin=kmin, xmax=kmax, win=win, delay_draw=True,_larch=_larch,
847 **kws)
849 for ipath in range(len(dataset.pathlist)):
850 plot_path_k(dataset, ipath, offset=(ipath+1)*offset,
851 kmin=kmin, kmax=kmax, new=False, delay_draw=True,
852 win=win, _larch=_larch)
853 #endfor
854 redraw(win=win, xmin=kmin, xmax=kmax, _larch=_larch)
855#enddef
857def plot_paths_r(dataset, offset=-0.25, rmax=None, show_mag=True,
858 show_real=False, show_imag=False, title=None, new=True,
859 win=1, delay_draw=False, _larch=None, **kws):
860 """
861 plot_paths_r(dataset, offset=-0.5, rmax=None, show_mag=True, show_real=False,
862 show_imag=False, new=True, win=1, **kws):
864 Plot chi(R) for model and all paths of a feffit dataset
866 Arguments
867 ----------
868 dataset feffit dataset, after running feffit()
869 offset vertical offset to use for paths for plot [-0.5]
870 rmax max R to show [None, end of data]
871 show_mag bool whether to plot |chi(R)| [True]
872 show_real bool whether to plot Re[chi(R)] [False]
873 show_imag bool whether to plot Im[chi(R)] [False]
874 title string for plot title [None, may use filename if available]
875 new bool whether to start a new plot [True]
876 delay_draw bool whether to delay draw until more traces are added [False]
877 win integer plot window to use [1]
878 kws additional keyword arguments are passed to plot()
879 """
880 kweight = dataset.transform.kweight
881 model = dataset.model
883 ylabel = plotlabels.chirlab(kweight, show_mag=show_mag,
884 show_real=show_real, show_imag=show_imag)
885 title = _get_title(dataset, title=title)
886 opts = dict(xlabel=plotlabels.r, ylabel=ylabel, xmax=rmax, new=new,
887 delay_draw=True, title=title, _larch=_larch)
888 opts.update(kws)
889 if show_mag:
890 _plot(model.r, model.chir_mag, label='|sum|', **opts)
891 opts['new'] = False
892 #endif
893 if show_real:
894 _plot(model.r, model.chir_re, label='Re[sum]', **opts)
895 opts['new'] = False
896 #endif
897 if show_imag:
898 _plot(model.r, model.chir_im, label='Im[sum]', **opts)
899 opts['new'] = False
900 #endif
902 for ipath in range(len(dataset.pathlist)):
903 plot_path_r(dataset, ipath, offset=(ipath+1)*offset,
904 show_mag=show_mag, show_real=show_real,
905 show_imag=show_imag, **opts)
906 #endfor
907 redraw(win=win, xmax=rmax,_larch=_larch)
908#enddef
911def extend_plotrange(x, y, xmin=None, xmax=None, extend=0.10):
912 """return plot limits to extend a plot range for x, y pairs"""
913 xeps = min(diff(x)) / 5.
914 if xmin is None:
915 xmin = min(x)
916 if xmax is None:
917 xmax = max(x)
919 xmin = max(min(x), xmin-5)
920 xmax = min(max(x), xmax+5)
922 i0 = index_of(x, xmin + xeps)
923 i1 = index_of(x, xmax + xeps) + 1
925 xspan = x[i0:i1]
926 xrange = max(xspan) - min(xspan)
927 yspan = y[i0:i1]
928 yrange = max(yspan) - min(yspan)
930 return (min(xspan) - extend * xrange,
931 max(xspan) + extend * xrange,
932 min(yspan) - extend * yrange,
933 max(yspan) + extend * yrange)
935def plot_prepeaks_baseline(dgroup, subtract_baseline=False, show_fitrange=True,
936 show_peakrange=True, win=1, _larch=None, **kws):
937 """Plot pre-edge peak baseline fit, as from `pre_edge_baseline` or XAS Viewer
939 dgroup must have a 'prepeaks' attribute
940 """
941 if not hasattr(dgroup, 'prepeaks'):
942 raise ValueError('Group needs prepeaks')
943 #endif
944 ppeak = dgroup.prepeaks
946 px0, px1, py0, py1 = extend_plotrange(dgroup.xdat, dgroup.ydat,
947 xmin=ppeak.emin, xmax=ppeak.emax)
949 title = "pre_edge baseline\n %s" % dgroup.filename
951 popts = dict(xmin=px0, xmax=px1, ymin=py0, ymax=py1, title=title,
952 xlabel='Energy (eV)', ylabel='mu (normalized)', delay_draw=True,
953 show_legend=True, style='solid', linewidth=3,
954 label='data', new=True,
955 marker='None', markersize=4, win=win, _larch=_larch)
956 popts.update(kws)
958 ydat = dgroup.ydat
959 xdat = dgroup.xdat
960 if subtract_baseline:
961 xdat = ppeak.energy
962 ydat = ppeak.baseline
963 popts['label'] = 'baseline subtracted peaks'
964 _plot(xdat, ydat, **popts)
965 else:
966 _plot(xdat, ydat, **popts)
967 popts['new'] = False
968 popts['label'] = 'baseline'
969 _oplot(ppeak.energy, ppeak.baseline, **popts)
971 popts = dict(win=win, _larch=_larch, delay_draw=True,
972 label='_nolegend_')
974 if show_fitrange:
975 for x in (ppeak.emin, ppeak.emax):
976 _plot_axvline(x, color='#DDDDCC', **popts)
977 _plot_axvline(ppeak.centroid, color='#EECCCC', **popts)
979 if show_peakrange:
980 for x in (ppeak.elo, ppeak.ehi):
981 y = ydat[index_of(xdat, x)]
982 _plot_marker(x, y, color='#222255', marker='o', size=8, **popts)
984 redraw(win=win, xmin=px0, xmax=px1, ymin=py0, ymax=py1,
985 show_legend=True, _larch=_larch)
986#enddef
988def plot_prepeaks_fit(dgroup, nfit=0, show_init=False, subtract_baseline=False,
989 show_residual=False, win=1, _larch=None):
990 """plot pre-edge peak fit, as from XAS Viewer
992 dgroup must have a 'peakfit_history' attribute
993 """
994 if not hasattr(dgroup, 'prepeaks'):
995 raise ValueError('Group needs prepeaks')
996 #endif
997 if show_init:
998 result = pkfit = dgroup.prepeaks
999 else:
1000 hist = getattr(dgroup.prepeaks, 'fit_history', None)
1001 if nfit > len(hist):
1002 nfit = 0
1003 pkfit = hist[nfit]
1004 result = pkfit.result
1005 #endif
1007 if pkfit is None:
1008 raise ValueError('Group needs prepeaks.fit_history or init_fit')
1009 #endif
1011 opts = pkfit.user_options
1012 xeps = min(diff(dgroup.xdat)) / 5.
1013 xdat = 1.0*pkfit.energy
1014 ydat = 1.0*pkfit.norm
1016 xdat_full = 1.0*dgroup.xdat
1017 ydat_full = 1.0*dgroup.ydat
1019 if show_init:
1020 yfit = pkfit.init_fit
1021 ycomps = None # pkfit.init_ycomps
1022 ylabel = 'model'
1023 else:
1024 yfit = 1.0*result.best_fit
1025 ycomps = pkfit.ycomps
1026 ylabel = 'best fit'
1028 baseline = 0.*ydat
1029 if ycomps is not None:
1030 for label, ycomp in ycomps.items():
1031 if label in opts['bkg_components']:
1032 baseline += ycomp
1034 plotopts = dict(title='%s:\npre-edge peak' % dgroup.filename,
1035 xlabel='Energy (eV)', ylabel=opts['array_desc'],
1036 delay_draw=True, show_legend=True, style='solid',
1037 linewidth=3, marker='None', markersize=4)
1039 if subtract_baseline:
1040 ydat -= baseline
1041 yfit -= baseline
1042 ydat_full = 1.0*ydat
1043 xdat_full = 1.0*xdat
1044 plotopts['ylabel'] = '%s-baseline' % plotopts['ylabel']
1046 dx0, dx1, dy0, dy1 = extend_plotrange(xdat_full, ydat_full,
1047 xmin=opts['emin'], xmax=opts['emax'])
1048 fx0, fx1, fy0, fy1 = extend_plotrange(xdat, yfit,
1049 xmin=opts['emin'], xmax=opts['emax'])
1051 ncolor = 0
1052 popts = {'win': win, '_larch': _larch}
1053 plotopts.update(popts)
1054 dymin = dymax = None
1055 if show_residual:
1056 popts['stacked'] = True
1057 _fitplot(xdat, ydat, yfit, label='data', label2=ylabel, **plotopts)
1058 dy = yfit - ydat
1059 dymax, dymin = dy.max(), dy.min()
1060 dymax += 0.05 * (dymax - dymin)
1061 dymin -= 0.05 * (dymax - dymin)
1062 else:
1063 _plot(xdat_full, ydat_full, new=True, label='data',
1064 color=LineColors[0], **plotopts)
1065 _oplot(xdat, yfit, label=ylabel, color=LineColors[1], **plotopts)
1066 ncolor = 1
1068 if ycomps is not None:
1069 ncomps = len(ycomps)
1070 if not subtract_baseline:
1071 ncolor += 1
1072 _oplot(xdat, baseline, label='baseline', delay_draw=True,
1073 style='short dashed', marker='None', markersize=5,
1074 color=LineColors[ncolor], **popts)
1076 for icomp, label in enumerate(ycomps):
1077 ycomp = ycomps[label]
1078 if label in opts['bkg_components']:
1079 continue
1080 ncolor = (ncolor+1) % 10
1081 _oplot(xdat, ycomp, label=label, delay_draw=(icomp != ncomps-1),
1082 style='short dashed', marker='None', markersize=5,
1083 color=LineColors[ncolor], **popts)
1085 if opts.get('show_fitrange', False):
1086 for attr in ('emin', 'emax'):
1087 _plot_axvline(opts[attr], ymin=0, ymax=1,
1088 delay_draw=False, color='#DDDDCC',
1089 label='_nolegend_', **popts)
1091 if opts.get('show_centroid', False):
1092 pcen = getattr(dgroup.prepeaks, 'centroid', None)
1093 if hasattr(result, 'params'):
1094 pcen = result.params.get('fit_centroid', None)
1095 if pcen is not None:
1096 pcen = pcen.value
1097 if pcen is not None:
1098 _plot_axvline(pcen, delay_draw=False, ymin=0, ymax=1,
1099 color='#EECCCC', label='_nolegend_', **popts)
1101 redraw(xmin=dx0, xmax=dx1, ymin=min(dy0, fy0),
1102 ymax=max(dy1, fy1), dymin=dymin, dymax=dymax, show_legend=True, **popts)
1104def _pca_ncomps(result, min_weight=0, ncomps=None):
1105 if ncomps is None:
1106 if min_weight > 1.e-12:
1107 ncomps = where(result.variances < min_weight)[0][0]
1108 else:
1109 ncomps = argmin(result.ind)
1110 return ncomps
1113def plot_pca_components(result, min_weight=0, ncomps=None, min_variance=1.e-5, win=1, _larch=None, **kws):
1114 """Plot components from PCA result
1116 result must be output of `pca_train`
1117 """
1118 title = "PCA components"
1119 popts = dict(xmin=result.xmin, xmax=result.xmax, title=title,
1120 xlabel=plotlabels.energy, ylabel=plotlabels.norm,
1121 delay_draw=True, show_legend=True, style='solid',
1122 linewidth=3, new=True, marker='None', markersize=4,
1123 win=win, _larch=_larch)
1125 popts.update(kws)
1126 ncomps = int(result.nsig)
1128 _plot(result.x, result.mean, label='Mean', **popts)
1129 for i, comp in enumerate(result.components):
1130 if result.variances[i] > min_variance:
1131 label = 'Comp# %d (%.4f)' % (i+1, result.variances[i])
1132 _oplot(result.x, comp, label=label, **popts)
1134 redraw(win=win, show_legend=True, _larch=_larch)
1136def plot_pca_weights(result, min_weight=0, ncomps=None, win=1, _larch=None, **kws):
1137 """Plot component weights from PCA result (aka SCREE plot)
1139 result must be output of `pca_train`
1140 """
1141 max_comps = len(result.components)
1143 title = "PCA Variances (SCREE) and Indicator Values"
1145 popts = dict(title=title, xlabel='Component #', zorder=10,
1146 xmax=max_comps+1.5, xmin=0.25, ymax=1, ylabel='variance',
1147 style='solid', ylog_scale=True, show_legend=True,
1148 linewidth=1, new=True, marker='o', win=win, _larch=_larch)
1150 popts.update(kws)
1152 ncomps = max(1, int(result.nsig))
1153 x = 1 + arange(ncomps)
1154 y = result.variances[:ncomps]
1155 _plot(x, y, label='significant', **popts)
1157 xe = 1 + arange(ncomps-1, max_comps)
1158 ye = result.variances[ncomps-1:ncomps+max_comps]
1160 popts.update(dict(new=False, zorder=5, style='short dashed',
1161 color='#B34050', ymin=2e-3*result.variances[ncomps-1]))
1162 _plot(xe, ye, label='not significant', **popts)
1164 xi = 1 + arange(len(result.ind)-1)
1166 _plot(xi, result.ind[1:], zorder=15, y2label='Indicator Value',
1167 label='IND', style='solid', win=win, show_legend=True,
1168 linewidth=1, marker='o', side='right', _larch=_larch)
1172def plot_pca_fit(dgroup, win=1, with_components=False, _larch=None, **kws):
1173 """Plot data and fit result from pca_fit, which rom PCA result
1175 result must be output of `pca_fit`
1176 """
1178 title = "PCA fit: %s" % (dgroup.filename)
1179 result = dgroup.pca_result
1180 model = result.pca_model
1182 popts = dict(xmin=model.xmin, xmax=model.xmax, title=title,
1183 xlabel=plotlabels.energy, ylabel=plotlabels.norm,
1184 delay_draw=True, show_legend=True, style='solid',
1185 linewidth=3, new=True, marker='None', markersize=4,
1186 stacked=True, win=win, _larch=_larch)
1187 popts.update(kws)
1188 _fitplot(result.x, result.ydat, result.yfit,
1189 label='data', label2='PCA fit', **popts)
1191 disp = get_display(win=win, stacked=True, _larch=_larch)
1192 if with_components and disp is not None:
1193 disp.panel.oplot(result.x, model.mean, label='mean')
1194 for n in range(len(result.weights)):
1195 cval = model.components[n]*result.weights[n]
1196 disp.panel.oplot(result.x, cval, label='Comp #%d' % (n+1))
1197 redraw(win=win, show_legend=True, stacked=True, _larch=_larch)
1199def plot_diffkk(dgroup, emin=None, emax=None, new=True, label=None,
1200 title=None, delay_draw=False, offset=0, win=1, _larch=None):
1201 """
1202 plot_diffkk(dgroup, norm=True, emin=None, emax=None, show_e0=False, label=None, new=True, win=1):
1204 Plot mu(E) and background mu0(E) for XAFS data group
1206 Arguments
1207 ----------
1208 dgroup group of XAFS data after autobk() results (see Note 1)
1209 norm bool whether to show normalized data [True]
1210 emin min energy to show, absolute or relative to E0 [None, start of data]
1211 emax max energy to show, absolute or relative to E0 [None, end of data]
1212 show_e0 bool whether to show E0 [False]
1213 label string for label [``None``: 'mu']
1214 title string for plot title [None, may use filename if available]
1215 new bool whether to start a new plot [True]
1216 delay_draw bool whether to delay draw until more traces are added [False]
1217 offset vertical offset to use for y-array [0]
1218 win integer plot window to use [1]
1220 Notes
1221 -----
1222 1. The input data group must have the following attributes:
1223 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
1224 """
1225 if hasattr(dgroup, 'f2'):
1226 f2 = dgroup.f2
1227 else:
1228 raise ValueError("Data group has no array for f2")
1229 #endif
1230 ylabel = r'$f \rm\,\, (e^{-})$ '
1231 emin, emax = _get_erange(dgroup, emin, emax)
1232 title = _get_title(dgroup, title=title)
1234 labels = {'f2': r"$f_2(E)$", 'fpp': r"$f''(E)$", 'fp': r"$f'(E)$", 'f1': r"$f_1(E)$"}
1236 opts = dict(win=win, show_legend=True, linewidth=3,
1237 delay_draw=True, _larch=_larch)
1239 _plot(dgroup.energy, f2, xlabel=plotlabels.energy, ylabel=ylabel,
1240 title=title, label=labels['f2'], zorder=20, new=new, xmin=emin, xmax=emax,
1241 **opts)
1242 zorder = 15
1243 for attr in ('fpp', 'f1', 'fp'):
1244 yval = getattr(dgroup, attr)
1245 if yval is not None:
1246 _plot(dgroup.energy, yval, zorder=zorder, label=labels[attr], **opts)
1247 zorder = zorder - 3
1249 redraw(win=win, xmin=emin, xmax=emax, _larch=_larch)
1250#enddef
1252def plot_feffdat(feffpath, with_phase=True, title=None,
1253 new=True, delay_draw=False, win=1, _larch=None):
1254 """
1255 plot_feffdat(feffpath, with_phase=True, title=None, new=True, win=1):
1257 Plot Feff's magnitude and phase as a function of k for a FeffPath
1259 Arguments
1260 ----------
1261 feffpath feff path as read by feffpath()
1262 with_pase whether to plot phase(k) as well as magnitude [True]
1263 title string for plot title [None, may use filename if available]
1264 new bool whether to start a new plot [True]
1265 delay_draw bool whether to delay draw until more traces are added [False]
1266 win integer plot window to use [1]
1268 Notes
1269 -----
1270 1. The input data group must have the following attributes:
1271 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
1272 """
1273 if hasattr(feffpath, '_feffdat'):
1274 fdat = feffpath._feffdat
1275 else:
1276 raise ValueError("must pass in a Feff path as from feffpath()")
1277 #endif
1279 _plot(fdat.k, fdat.mag_feff, xlabel=plotlabels.k,
1280 ylabel='|F(k)|', title=title, label='magnitude', zorder=20,
1281 new=new, win=win, show_legend=True,
1282 delay_draw=delay_draw, linewidth=3, _larch=_larch)
1284 if with_phase:
1285 _plot(fdat.k, fdat.pha_feff, xlabel=plotlabels.k,
1286 y2label='Phase(k)', title=title, label='phase', side='right',
1287 zorder=10, new=False, win=win, show_legend=True,
1288 delay_draw=delay_draw, linewidth=3, _larch=_larch)
1289 #endif
1291 if delay_draw:
1292 redraw(win=win, xmin=emin, xmax=emax, _larch=_larch)
1293#enddef