Coverage for larch/plot/plotly_xafsplots.py: 0%
611 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"""
21import os
22import numpy as np
23import time
24import logging
25from copy import deepcopy
27from larch import Group
28from larch.math import index_of
29from larch.xafs import cauchy_wavelet, etok
31def nullfunc(*args, **kws):
32 pass
34get_display = _plot = _oplot = _newplot = _fitplot = _plot_text = nullfunc
36HAS_PLOTLY = True
37try:
38 import plotly
39except ImportError:
40 HAS_PLOTLY = False
42if HAS_PLOTLY:
43 import plotly.graph_objs as pgo
44 from plotly.subplots import make_subplots
46LineColors = ('#1f77b4', '#d62728', '#2ca02c', '#ff7f0e', '#9467bd',
47 '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf')
48LineStyles = ('solid', 'dashed', 'dotted')
49NCOLORS = len(LineColors)
50NSTYLES = len(LineStyles)
52FIGSTYLE = dict(width=650, height=500,
53 showlegend=True, hovermode='closest',
54 legend=dict(borderwidth=0.5, bgcolor='#F2F2F2'),
55 # orientation='v') #, x=0.1, y=1.15)# , yanchor='top'),
56 plot_bgcolor='#FDFDFF',
57 xaxis=dict(showgrid=True, gridcolor='#D8D8D8',
58 color='#004', zerolinecolor='#DDD'),
59 yaxis=dict(showgrid=True, gridcolor='#D8D8D8',
60 color='#004', zerolinecolor='#DDD')
61 )
63def set_label_weight(label, w):
64 return label.replace('_w_', '{0:g}'.format(w))
66# common XAFS plot labels
67def chirlab(kweight, show_mag=True, show_real=False, show_imag=False):
68 """generate chi(R) label for a kweight
70 Arguments
71 ----------
72 kweight k-weight to use (required)
73 show_mag bool whether to plot |chi(R)| [True]
74 show_real bool whether to plot Re[chi(R)] [False]
75 show_imag bool whether to plot Im[chi(R)] [False]
76 """
77 ylab = []
78 if show_mag: ylab.append(plotlabels.chirmag)
79 if show_real: ylab.append(plotlabels.chirre)
80 if show_imag: ylab.append(plotlabels.chirim)
81 if len(ylab) > 1: ylab = [plotlabels.chir]
82 return set_label_weight(ylab[0], kweight+1)
83#enddef
85# note:
86# to make life easier for MathJax/Plotly/IPython
87# we have just replaced "\AA" with "\unicode{x212B}"
88plotlabels = Group(k = r'$k \rm\,(\unicode{x212B}^{-1})$',
89 r = r'$R \rm\,(\unicode{x212B})$',
90 energy = r'$E\rm\,(eV)$',
91 ewithk = r'$E\rm\,(eV)$' + '\n' + r'$[k \rm\,(\unicode{x212B}^{-1})]$',
92 mu = r'$\mu(E)$',
93 norm = r'normalized $\mu(E)$',
94 flat = r'flattened $\mu(E)$',
95 deconv = r'deconvolved $\mu(E)$',
96 dmude = r'$d\mu_{\rm norm}(E)/dE$',
97 d2mude = r'$d^2\mu_{\rm norm}(E)/dE^2$',
98 chie = r'$\chi(E)$',
99 chie0 = r'$\chi(E)$',
100 chie1 = r'$E\chi(E) \rm\, (eV)$',
101 chiew = r'$E^{{_w_}\chi(E) \rm\,(eV^{_w_})$',
102 chikw = r'$k^{{_w_}}\chi(k) \rm\,(\unicode{x212B}^{{-_w_}})$',
103 chi0 = r'$\chi(k)$',
104 chi1 = r'$k\chi(k) \rm\,(\unicode{x212B}^{-1})$',
105 chi2 = r'$k^2\chi(k) \rm\,(\unicode{x212B}^{-2})$',
106 chi3 = r'$k^3\chi(k) \rm\,(\unicode{x212B}^{-3})$',
107 chir = r'$\chi(R) \rm\,(\unicode{x212B}^{{-_w_}})$',
108 chirmag = r'$|\chi(R)| \rm\,(\unicode{x212B}^{{-_w_}})$',
109 chirre = r'${{\rm Re}}[\chi(R)] \rm\,(\unicode{x212B}^{{-_w_}})$',
110 chirim = r'${{\rm Im}}[\chi(R)] \rm\,(\unicode{x212B}^{{-_w_}})$',
111 chirpha = r'${{\rm Phase}}[\chi(R)] \rm\,(\unicode{x212B}^{{-_w_}})$',
112 e0color = '#B2B282',
113 chirlab = chirlab)
116def safetitle(t):
117 if "'" in t:
118 t = t.replace("'", "\\'")
119 return t
121def _get_title(dgroup, title=None):
122 """get best title for group"""
123 if title is not None:
124 return safetitle(title)
125 data_group = getattr(dgroup, 'data', None)
127 for attr in ('title', 'plot_title', 'filename', 'name', '__name__'):
128 t = getattr(dgroup, attr, None)
129 if t is not None:
130 if attr == 'filename':
131 folder, file = os.path.split(t)
132 if folder == '':
133 t = file
134 else:
135 top, folder = os.path.split(folder)
136 t = '/'.join((folder, file))
137 return safetitle(t)
138 if data_group is not None:
139 t = getattr(data_group, attr, None)
140 if t is not None:
141 return t
142 return safetitle(repr(dgroup))
145def _get_kweight(dgroup, kweight=None):
146 if kweight is not None:
147 return kweight
148 callargs = getattr(dgroup, 'callargs', None)
149 ftargs = getattr(callargs, 'xftf', {'kweight':0})
150 return ftargs['kweight']
152def _get_erange(dgroup, emin=None, emax=None):
153 """get absolute emin/emax for data range, allowing using
154 values relative to e0.
155 """
156 dat_emin, dat_emax = min(dgroup.energy)-100, max(dgroup.energy)+100
157 e0 = getattr(dgroup, 'e0', 0.0)
158 if emin is not None:
159 if not (emin > dat_emin and emin < dat_emax):
160 if emin+e0 > dat_emin and emin+e0 < dat_emax:
161 emin += e0
162 else:
163 emin = dat_emin
164 if emax is not None:
165 if not (emax > dat_emin and emax < dat_emax):
166 if emax+e0 > dat_emin and emax+e0 < dat_emax:
167 emax += e0
168 else:
169 emax = dat_emax
170 return emin, emax
172def extend_plotrange(x, y, xmin=None, xmax=None, extend=0.10):
173 """return plot limits to extend a plot range for x, y pairs"""
174 xeps = min(np.diff(x)) / 5.
175 if xmin is None:
176 xmin = min(x)
177 if xmax is None:
178 xmax = max(x)
180 xmin = max(min(x), xmin-5)
181 xmax = min(max(x), xmax+5)
183 i0 = index_of(x, xmin + xeps)
184 i1 = index_of(x, xmax + xeps) + 1
186 xspan = x[i0:i1]
187 xrange = max(xspan) - min(xspan)
188 yspan = y[i0:i1]
189 yrange = max(yspan) - min(yspan)
191 return (min(xspan) - extend * xrange,
192 max(xspan) + extend * xrange,
193 min(yspan) - extend * yrange,
194 max(yspan) + extend * yrange)
197def redraw(win=1, xmin=None, xmax=None, ymin=None, ymax=None,
198 dymin=None, dymax=None,
199 show_legend=True, stacked=False):
200 pass
203class PlotlyFigure:
204 """wrapping of Plotly Figure
205 """
206 def __init__(self, two_yaxis=False, style=None):
207 self.two_yaxis = two_yaxis
208 self.style = deepcopy(FIGSTYLE)
209 if style is not None:
210 self.style.update(style)
211 if self.two_yaxis:
212 self.fig = make_subplots(specs=[[{"secondary_y": True}]])
213 else:
214 self.fig = pgo.FigureWidget()
216 self.traces = []
218 def clear(self):
219 self.traces = []
221 def add_plot(self, x, y, label=None, color=None, linewidth=3,
222 style='solid', marker=None, side='left'):
223 itrace = len(self.traces)
225 if label is None:
226 label = "trace %d" % (1+itrace)
227 if color is None:
228 color = LineColors[itrace % NCOLORS]
229 if style is None:
230 style = LineStyles[ int(itrace*1.0 / NCOLORS) % NSTYLES]
232 trace_opts = {}
233 if self.two_yaxis:
234 trace_opts['secondary_y'] = (side.lower().startswith('r'))
236 lineopts = dict(color=color, width=linewidth)
237 trace = pgo.Scatter(x=x, y=y, name=label, line=lineopts)
239 self.traces.append(trace)
241 self.fig.add_trace(trace, **trace_opts)
243 def add_vline(self, *args, **kws):
244 self.fig.add_vline(*args, **kws)
246 def set_xrange(self, xmin, xmax):
247 self.fig.update_xaxes(range=[xmin, xmax])
249 def set_yrange(self, ymin, ymax):
250 self.fig.update_yaxes(range=[ymin, ymax])
252 def set_ylog(self, ylog=True):
253 ytype = 'log' if ylog else 'linear'
254 self.fig.update_yaxes(type=ytype)
256 def set_style(self, **kws):
257 self.style.update(**kws)
258 self.fig.update_layout(**self.style)
260 def show(self, title=None, xlabel=None, ylabel=None,
261 xmin=None, xmax=None, ymin=None, ymax=None, show=True):
262 self.set_style(title=title, xaxis_title=xlabel, yaxis_title=ylabel)
263 if xmin is not None or xmax is not None:
264 self.set_xrange(xmin, xmax)
265 if ymin is not None or ymax is not None:
266 self.set_yrange(ymin, ymax)
267 if show:
268 self.fig.show()
269 return self
271def plot(xdata, ydata, dy=None, fig=None, label=None, xlabel=None,
272 ylabel=None, y2label=None, title=None, side='left', ylog_scale=None,
273 xlog_scale=None, grid=None, xmin=None, xmax=None, ymin=None,
274 ymax=None, color=None, style='solid', alpha=None, fill=False,
275 drawstyle=None, linewidth=2, marker=None, markersize=None,
276 show_legend=None, bgcolor=None, framecolor=None, gridcolor=None,
277 textcolor=None, labelfontsize=None, titlefontsize=None,
278 legendfontsize=None, fullbox=None, axes_style=None, zorder=None, show=True):
279 """emulate wxmplot plot() function, probably incompletely"""
281 if fig is None:
282 fig = PlotlyFigure(two_yaxis=(side=='right'))
284 fig.add_plot(xdata, ydata, label=label, color=color, linewidth=linewidth,
285 style=style, marker=marker, side=side)
287 return fig.show(title=title, xlabel=xlabel, ylabel=ylabel,
288 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, show=show)
291def multi_plot(plotsets):
292 """plot multiple traces with an array of dictionaries emulating
293 multiplot calls to plot:
295 instead of
297 >>> plot(x1, y1, label='thing1', color='blue')
298 >>> plot(x2, y2, label='thing2', color='red')
300 you can do
302 >>> multi_plot([dict(xdata=x1, ydata=y1, label='thing1', color='blue'),
303 dict(xdata=x2, ydata=y2, label='thing2', color='red')])
305 """
306 two_axis = False
307 for pset in plotsets[:]:
308 side = pset.get('side', None)
309 if side == 'right':
310 two_axis = True
313 fig = PlotlyFigure(two_yaxis=two_axis)
314 fig.clear()
316 sopts = dict(title=None, xlabel=None, ylabel=None)
317 ropts = dict(xmin=None, xmax=None, ymin=None, ymax=None)
319 for pset in plotsets[:]:
320 xdata = pset['xdata']
321 ydata = pset['ydata']
322 popts = dict(label=None, color=None, side='left', style=None,
323 linewidth=3, marker=None)
324 for w in ('label', 'color', 'style', 'linewidth', 'marker', 'side'):
325 if w in pset:
326 popts[w] = pset[w]
327 for w in ('title', 'xlabel', 'ylabel'):
328 if w in pset:
329 sopts[w] = pset[w]
331 for w in ('xmin', 'xmax', 'ymin', 'ymax'):
332 if w in pset:
333 ropts[w] = pset[w]
335 fig.add_plot(xdata, ydata, **popts)
337 sopts['xaxis_title'] = sopts.pop('xlabel')
338 sopts['yaxis_title'] = sopts.pop('ylabel')
339 fig.style.update(sopts)
340 return fig.show(**ropts)
342def plot_mu(dgroup, show_norm=False, show_flat=False, show_deriv=False,
343 show_pre=False, show_post=False, show_e0=False, with_deriv=False,
344 emin=None, emax=None, label='mu', offset=0, title=None, fig=None, show=True):
345 """
346 plot_mu(dgroup, norm=False, deriv=False, show_pre=False, show_post=False,
347 show_e0=False, show_deriv=False, emin=None, emax=None, label=None,
348 show=True, fig=None)
350 Plot mu(E) for an XAFS data group in various forms
352 Arplguments
353 ----------
354 dgroup group of XAFS data after pre_edge() results (see Note 1)
355 show_norm bool whether to show normalized data [False]
356 show_flat bool whether to show flattened, normalized data [False]
357 show_deriv bool whether to show derivative of normalized data [False]
358 show_pre bool whether to show pre-edge curve [False]
359 show_post bool whether to show post-edge curve [False]
360 show_e0 bool whether to show E0 [False]
361 with_deriv bool whether to show deriv (dmu/de) together with mu [False]
362 emin min energy to show, absolute or relative to E0 [None, start of data]
363 emax max energy to show, absolute or relative to E0 [None, end of data]
364 label string for label [None: 'mu', `dmu/dE', or 'mu norm']
365 title string for plot title [None, may use filename if available]
366 offset vertical offset to use for y-array [0]
367 show display the PlotlyFig now [True]
368 fig PlotlyFig to reuse [None]
370 Notes
371 -----
372 1. The input data group must have the following attributes:
373 energy, mu, norm, e0, pre_edge, edge_step
374 """
375 if not HAS_PLOTLY:
376 logging.getLogger().error('Need plotply installed')
377 return
379 if hasattr(dgroup, 'mu'):
380 mu = dgroup.mu
381 elif hasattr(dgroup, 'mutrans'):
382 mu = dgroup.mutrans
383 elif hasattr(dgroup, 'mufluor'):
384 mu = dgroup.mufluor
385 else:
386 raise ValueError("XAFS data group has no array for mu")
387 #endif
388 ylabel = plotlabels.mu
389 if label is None:
390 label = getattr(dgroup, 'filename', 'mu')
391 #endif
392 if show_deriv:
393 mu = dgroup.dmude
394 ylabel = f"{ylabel} (deriv)"
395 dlabel = plotlabels.dmude
396 elif show_norm:
397 mu = dgroup.norm
398 ylabel = f"{ylabel} (norm)"
399 dlabel = plotlabels.norm
400 #endif
401 elif show_flat:
402 mu = dgroup.flat
403 ylabel = f"{ylabel} (flat)"
404 dlabel = plotlabels.flat
405 #endif
406 emin, emax = _get_erange(dgroup, emin, emax)
407 title = _get_title(dgroup, title=title)
409 if fig is None:
410 fig = PlotlyFigure(two_yaxis=with_deriv)
411 fig.add_plot(dgroup.energy, mu+offset, label=label)
413 if with_deriv:
414 fig.add_plot(dgroup.energy, dgroup.dmude+offset, label=f"{ylabel} (deriv)", side='right')
415 fig.fig.update_yaxis(title_text=plotlabels.dmude, secondary_y=True)
416 else:
417 if not show_norm and show_pre:
418 fig.add_plot(dgroup.energy, dgroup.pre_edge+offset, label='pre_edge')
419 if not show_norm and show_post:
420 fig.add_plot(dgroup.energy, dgroup.post_edge+offset, label='post_edge')
422 if show_e0:
423 fig.add_vline(x=dgroup.e0, line_width=2, line_dash="dash", line_color="#AAC")
425 return fig.show(title=title, xlabel=plotlabels.energy, ylabel=ylabel,
426 xmin=emin, xmax=emax, show=show)
429def plot_bkg(dgroup, norm=True, emin=None, emax=None, show_e0=False,
430 label=None, title=None, offset=0):
431 """
432 plot_bkg(dgroup, norm=True, emin=None, emax=None, show_e0=False, label=None, new=True)
434 Plot mu(E) and background mu0(E) for XAFS data group
436 Arguments
437 ----------
438 dgroup group of XAFS data after autobk() results (see Note 1)
439 norm bool whether to show normalized data [True]
440 emin min energy to show, absolute or relative to E0 [None, start of data]
441 emax max energy to show, absolute or relative to E0 [None, end of data]
442 show_e0 bool whether to show E0 [False]
443 label string for label [``None``: 'mu']
444 title string for plot titlte [None, may use filename if available]
445 offset vertical offset to use for y-array [0]
447 Notes
448 -----
449 1. The input data group must have the following attributes:
450 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
451 """
452 if hasattr(dgroup, 'mu'):
453 mu = dgroup.mu
454 elif hasattr(dgroup, 'mutrans'):
455 mu = dgroup.mutrans
456 else:
457 raise ValueError("XAFS data group has no array for mu")
459 bkg = dgroup.bkg
460 ylabel = plotlabels.mu
461 if label is None:
462 label = 'mu'
464 emin, emax = _get_erange(dgroup, emin, emax)
465 if norm:
466 mu = dgroup.norm
467 bkg = (dgroup.bkg - dgroup.pre_edge) / dgroup.edge_step
468 ylabel = f"{ylabel} (norm)"
469 label = f"{ylabel} (norm)"
470 #endif
471 title = _get_title(dgroup, title=title)
473 fig = PlotlyFigure(two_yaxis=False)
474 fig.add_plot(dgroup.energy, mu+offset, label=label)
475 fig.add_plot(dgroup.energy, bkg+offset, label='bkg')
477 if show_e0:
478 fig.add_vline(x=dgroup.e0, line_width=2, line_dash="dash", line_color="#AAC")
480 return fig.show(title=title, xlabel=plotlabels.energy, ylabel=ylabel, xmin=emin, xmax=emax)
483def plot_chie(dgroup, emin=-5, emax=None, label=None, title=None,
484 eweight=0, offset=0, how_k=False, fig=None, show=True):
485 """
486 plot_chie(dgroup, emin=None, emax=None, label=None, new=True, fig=None):
488 Plot chi(E) for XAFS data group
490 Arguments
491 ----------
492 dgroup group of XAFS data after autobk() results (see Note 1)
493 emin min energy to show, absolute or relative to E0 [-25]
494 emax max energy to show, absolute or relative to E0 [None, end of data]
495 label string for label [``None``: 'mu']
496 title string for plot title [None, may use filename if available]
497 eweight energy weightingn for energisdef es>e0 [0]
498 offset vertical offset to use for y-array [0]
499 show display the PlotlyFig now [True]
500 fig PlotlyFigure to re-use [None]
502 Notes
503 -----
504 1. The input data group must have the following attributes:
505 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
506 """
507 if hasattr(dgroup, 'mu'):
508 mu = dgroup.mu
509 elif hasattr(dgroup, 'mutrans'):
510 mu = dgroup.mutrans
511 else:
512 raise ValueError("XAFS data group has no array for mu")
513 #endif
514 e0 = dgroup.e0
515 chie = (mu - dgroup.bkg)
516 ylabel = plotlabels.chie
517 if abs(eweight) > 1.e-2:
518 chie *= (dgroup.energy-e0)**(eweight)
519 ylabel = set_label_weight(plotlabels.chiew, eweight)
520 xlabel = plotlabels.energy
522 emin, emax = _get_erange(dgroup, emin, emax)
523 if emin is not None:
524 emin = emin - e0
525 if emax is not None:
526 emax = emax - e0
528 title = _get_title(dgroup, title=title)
529 def ek_formatter(x, pos):
530 ex = float(x)
531 if ex < 0:
532 s = ''
533 else:
534 s = f"\n[{etok(ex):.2f}]"
535 return r"%1.4g%s" % (x, s)
537 if fig is None:
538 fig = PlotlyFigure(two_yaxis=False)
539 fig.add_plot(dgroup.energy-e0, chie+offset, label=label)
540 return fig.show(title=title, xlabel=xlabel, ylabel=ylabel, xmin=emin, xmax=emax, show=show)
542def plot_chik(dgroup, kweight=None, kmax=None, show_window=True,
543 scale_window=True, label=None, title=None, offset=0, show=True, fig=None):
544 """
545 plot_chik(dgroup, kweight=None, kmax=None, show_window=True, label=None,
546 fig=None)
548 Plot k-weighted chi(k) for XAFS data group
550 Arguments
551 ----------
552 dgroup group of XAFS data after autobk() results (see Note 1)
553 kweight k-weighting for plot [read from last xftf(), or 0]
554 kmax max k to show [None, end of data]
555 show_window bool whether to also plot k-window [True]
556 scale_window bool whether to scale k-window to max |chi(k)| [True]
557 label string for label [``None`` to use 'chi']
558 title string for plot title [None, may use filename if available]
559 offset vertical offset to use for y-array [0]
560 show display the PlotlyFig now [True]
561 fig PlotlyFigure to re-use [None]
563 Notes
564 -----
565 1. The input data group must have the following attributes:
566 k, chi, kwin, filename
567 """
568 kweight = _get_kweight(dgroup, kweight)
569 chi = dgroup.chi * dgroup.k ** kweight
571 if label is None:
572 label = 'chi'
574 title = _get_title(dgroup, title=title)
576 if fig is None:
577 fig = PlotlyFigure(two_yaxis=False)
578 fig.add_plot(dgroup.k, chi+offset, label=label)
580 if show_window and hasattr(dgroup, 'kwin'):
581 kwin = dgroup.kwin
582 if scale_window:
583 kwin = kwin*max(abs(chi))
584 fig.add_plot(dgroup.k, kwin+offset, label='window')
586 return fig.show(title=title, xlabel=plotlabels.k, xmin=0, xmax=kmax,
587 ylabel=set_label_weight(plotlabels.chikw, kweight),
588 show=show)
590def plot_chir(dgroup, show_mag=True, show_real=False, show_imag=False,
591 show_window=False, rmax=None, label=None, title=None,
592 offset=0, show=True, fig=None):
593 """
594 plot_chir(dgroup, show_mag=True, show_real=False, show_imag=False,
595 rmax=None, label=None, fig=None)
597 Plot chi(R) for XAFS data group
599 Arguments
600 ----------
601 dgroup group of XAFS data after xftf() results (see Note 1)
602 show_mag bool whether to plot |chi(R)| [True]
603 show_real bool whether to plot Re[chi(R)] [False]
604 show_imag bool whether to plot Im[chi(R)] [False]
605 show_window bool whether to R-windw for back FT (will be scaled) [False]
606 label string for label [``None`` to use 'chir']
607 title string for plot title [None, may use filename if available]
608 rmax max R to show [None, end of data]
609 offset vertical offset to use for y-array [0]
610 show display the PlotlyFig now [True]
611 fig PlotlyFigure to re-use [None]
613 Notes
614 -----
615 1. The input data group must have the following attributes:
616 r, chir_mag, chir_im, chir_re, kweight, filename
617 """
618 kweight = _get_kweight(dgroup, None)
620 title = _get_title(dgroup, title=title)
622 ylabel = plotlabels.chirlab(kweight, show_mag=show_mag,
623 show_real=show_real, show_imag=show_imag)
625 if not hasattr(dgroup, 'r'):
626 print("group does not have chi(R) data")
627 return
628 #endif
629 if label is None:
630 label = 'chir'
632 if fig is None:
633 fig = PlotlyFigure(two_yaxis=False)
634 if show_mag:
635 fig.add_plot(dgroup.r, dgroup.chir_mag+offset, label=f'{label} (mag)')
636 if show_real:
637 fig.add_plot(dgroup.r, dgroup.chir_re+offset, label=f'{label} (real)')
639 if show_imag:
640 fig.add_plot(dgroup.r, dgroup.chir_im+offset, label=f'{label} (imag)')
642 if show_window and hasattr(dgroup, 'rwin'):
643 rwin = dgroup.rwin * max(dgroup.chir_mag)
644 fig.add_plot(dgroup.r, rwin+offset, label='window')
646 return fig.show(title=title, xlabel=plotlabels.r, ylabel=ylabel, xmax=rmax, show=show)
649def plot_chiq(dgroup, kweight=None, kmin=0, kmax=None, show_chik=False, label=None,
650 title=None, offset=0, show_window=False, scale_window=True,
651 show=True, fig=None):
652 """
653 plot_chiq(dgroup, kweight=None, kmax=None, show_chik=False, label=None,
654 new=True, win=1)
656 Plot Fourier filtered chi(k), optionally with k-weighted chi(k) for XAFS data group
658 Arguments
659 ----------
660 dgroup group of XAFS data after autobk() results (see Note 1)
661 kweight k-weighting for plot [read from last xftf(), or 0]
662 kmax max k to show [None, end of data]
663 show_chik bool whether to also plot k-weighted chi(k) [False]
664 show_window bool whether to also plot FT k-window [False]
665 scale_window bool whether to scale FT k-window to max |chi(q)| [True]
666 label string for label [``None`` to use 'chi']
667 title string for plot title [None, may use filename if available]
668 offset vertical offset to use for y-array [0]
669 show display the PlotlyFig now [True]
670 fig PlotlyFigure to re-use [None]
672 Notes
673 -----
674 1. The input data group must have the following attributes:
675 k, chi, kwin, filename
676 """
677 kweight = _get_kweight(dgroup, kweight)
678 nk = len(dgroup.k)
679 chiq = dgroup.chiq_re[:nk]
681 if label is None:
682 label = 'chi(q) (filtered)'
684 title = _get_title(dgroup, title=title)
685 if fig is None:
686 fig = PlotlyFigure(two_yaxis=False)
687 fig.add_plot(dgroup.k, chiq+offset, label=label)
688 if kmax is None:
689 kmax = max(dgroup.k)
691 if show_chik:
692 chik = dgroup.chi * dgroup.k ** kweight
693 fig.add_plot(dgroup.k, chik+offset, label='chi(k) (unfiltered)')
695 if show_window and hasattr(dgroup, 'kwin'):
696 kwin = dgroup.kwin
697 if scale_window:
698 kwin = kwin*max(abs(chiq))
699 fig.add_plot(dgroup.k, kwin+offset, label='window')
701 ylabel = set_label_weight(plotlabels.chikw, kweight)
702 return fig.show(title=title, xlabel=plotlabels.k,
703 ylabel=ylabel, xmin=kmin, xmax=kmax, show=show)
707def plot_chifit(dataset, kmin=0, kmax=None, kweight=None, rmax=None,
708 show_mag=True, show_real=False, show_imag=False,
709 show_bkg=False, use_rebkg=False, title=None, offset=0):
710 """
711 plot_chifit(dataset, kmin=0, kmax=None, rmax=None,
712 show_mag=True, show_real=False, show_imag=False)
714 Plot k-weighted chi(k) and chi(R) for fit to feffit dataset
716 Arguments
717 ----------
718 dataset feffit dataset, after running feffit()
719 kmin min k to show [0]
720 kmax max k to show [None, end of data]
721 kweight kweight to show [None, taken from dataset]
722 rmax max R to show [None, end of data]
723 show_mag bool whether to plot |chidr(R)| [True]
724 show_real bool whether to plot Re[chi(R)] [False]
725 show_imag bool whether to plot Im[chi(R)] [False]
726 title string for plot title [None, may use filename if available]
727 offset vertical offset to use for y-array [0]
730 """
731 if kweight is None:
732 kweight = dataset.transform.kweight
733 #endif
734 if isinstance(kweight, (list, tuple, np.ndarray)):
735 kweight=kweight[0]
737 title = _get_title(dataset, title=title)
739 mod = dataset.model
740 dat = dataset.data
741 if use_rebkg and hasattr(dataset, 'data_rebkg'):
742 dat = dataset.data_rebkg
743 title += ' (refined bkg)'
745 data_chik = dat.chi * dat.k**kweight
746 model_chik = mod.chi * mod.k**kweight
748 # k-weighted chi(k) in first plot window
749 fig = PlotlyFigure(two_yaxis=False)
750 fig.add_plot(dat.k, data_chik+offset, label='data')
751 fig.add_plot(mod.k, model_chik+offset, label='fit')
753 ylabel = set_label_weight(plotlabels.chikw, kweight)
754 fig.show(title=title, xlabel=plotlabels.k,
755 ylabel=ylabel, xmin=kmin, xmax=kmax)
757 # chi(R) in first plot window
758 rfig = PlotlyFigure(two_yaxis=False)
760 if show_mag:
761 rfig.add_plot(dat.r, dat.chir_mag+offset, label='|data|')
762 rfig.add_plot(mod.r, mod.chir_mag+offset, label='|fit|')
764 if show_real:
765 rfig.add_plot(dat.r, dat.chir_re+offset, label='Re[data]')
766 rfig.add_plot(mod.r, mod.chir_re+offset, label='Re[fit]')
767 if show_imag:
768 rfig.add_plot(dat.r, dat.chir_im+offset, label='Im[data]')
769 rfig.add_plot(mod.r, mod.chir_im+offset, label='Im[fit]')
771 ylabel = chirlab(kweight, show_mag=show_mag, show_real=show_real, show_imag=show_imag)
772 rfig.show(title=title, xlabel=plotlabels.r, ylabel=ylabel, xmin=0, xmax=rmax)
773 return fig, rfig
775def plot_path_k(dataset, ipath=0, kmin=0, kmax=None, offset=0, label=None, fig=None):
776 """
777 plot_path_k(dataset, ipath, kmin=0, kmax=None, offset=0, label=None)
779 Plot k-weighted chi(k) for a single Path of a feffit dataset
781 Arguments
782 ----------
783 dataset feffit dataset, after running feffit()
784 ipath index of path, starting count at 0 [0]
785 kmin min k to show [0]
786 kmax max k to show [None, end of data]
787 offset vertical offset to use for plot [0]
788 label path label ['path %d' % ipath]
789 fig PlotlyFigure for reuse
790 """
791 kweight = dataset.transform.kweight
792 path = dataset.pathlist[ipath]
793 if label is None:
794 label = 'path %i' % (1+ipath)
795 title = _get_title(dataset, title=title)
797 chi_kw = offset + path.chi * path.k**kweight
798 if fig is None:
799 fig = PlotlyFigure(two_yaxis=False)
800 fig.add_plot(path.k, chi_kw, label=label)
801 return fig.set_style(title=title, xlabel=plotlabels.k,
802 yabel=set_label_weight(plotlabels.chikw, kweight),
803 xmin=kmin, xmax=kmax)
805def plot_path_r(dataset, ipath, rmax=None, offset=0, label=None,
806 show_mag=True, show_real=False, show_imag=True, fig=None):
807 """
808 plot_path_r(dataset, ipath,rmax=None, offset=0, label=None,
809 show_mag=True, show_real=False, show_imag=True, fig=None)
811 Plot chi(R) for a single Path of a feffit dataset
813 Arguments
814 ----------
815 dataset feffit dataset, after running feffit()
816 ipath index of path, starting count at 0 [0]
817 rmax max R to show [None, end of data]
818 offset vertical offset to use for plot [0]
819 label path label ['path %d' % ipath]
820 show_mag bool whether to plot |chi(R)| [True]
821 show_real bool whether to plot Re[chi(R)] [False]
822 show_imag bool whether to plot Im[chi(R)] [False]
823 fig PlotlyFigure for reuse
824 """
825 path = dataset.pathlist[ipath]
826 if label is None:
827 label = 'path %i' % (1+ipath)
829 title = _get_title(dataset, title=title)
830 kweight =dataset.transform.kweight
831 ylabel = plotlabels.chirlab(kweight, show_mag=show_mag,
832 show_real=show_real, show_imag=show_imag)
834 if fig is None:
835 fig = PlotlyFigure(two_yaxis=False)
836 if show_mag:
837 fig.add_plot(path.r, offset+path.chir_mag, label=f'|{label}|')
839 if show_real:
840 fig.add_plot(path.r, offset+path.chir_re, label=f'Re[{label}|')
842 if show_imag:
843 fig.add_plot(path.r, offset+path.chir_im, label=f'Im[{label}|')
845 return fig.show(title=title, xlabel=plotlabels.r, ylabel=chirlab(kweight),
846 xmax=rmax)
849def plot_paths_k(dataset, offset=-1, kmin=0, kmax=None, title=None, fig=None):
850 """
851 plot_paths_k(dataset, offset=-1, kmin=0, kmax=None, fig=None)
853 Plot k-weighted chi(k) for model and all paths of a feffit dataset
855 Arguments
856 ----------
857 dataset feffit dataset, after running feffit()
858 kmin min k to show [0]
859 kmax max k to show [None, end of data]
860 offset vertical offset to use for paths for plot [-1]
861 title string for plot title [None, may use filename if available]
862 fig PlotlyFigure for reuse
863 """
864 # make k-weighted chi(k)
865 kweight = dataset.transform.kweight
866 model = dataset.model
868 model_chi_kw = model.chi * model.k**kweight
870 title = _get_title(dataset, title=title)
871 if fig is None:
872 fig = PlotlyFigure(two_yaxis=False)
873 fig.add_plot(model.k, model_chi_kw, label='sum')
875 for ipath in range(len(dataset.pathlist)):
876 path = dataset.pathlist[ipath]
877 label = 'path %i' % (1+ipath)
878 chi_kw = offset*(1+ipath) + path.chi * path.k**kweight
879 fig.add_plot(path.k, chi_kw, label=label)
881 return fig.show(title=title, xlabel=plotlabels.k,
882 ylabel=set_label_weight(plotlabels.chikw, kweight),
883 xmin=kmin, xmax=kmax)
885def plot_paths_r(dataset, offset=-0.25, rmax=None, show_mag=True,
886 show_real=False, show_imag=False, title=None, fig=None):
887 """
888 plot_paths_r(dataset, offset=-0.5, rmax=None, show_mag=True, show_real=False,
889 show_imag=False)
891 Plot chi(R) for model and all paths of a feffit dataset
893 Arguments
894 ----------
895 dataset feffit dataset, after running feffit()
896 offset vertical offset to use for paths for plot [-0.5]
897 rmax max R to show [None, end of data]
898 show_mag bool whether to plot |chi(R)| [True]
899 show_real bool whether to plot Re[chi(R)] [False]
900 show_imag bool whether to plot Im[chi(R)] [False]
901 title string for plot title [None, may use filename if available]
902 fig PlotlyFigure for reuse
903 """
904 kweight = dataset.transform.kweight
905 model = dataset.model
907 title = _get_title(dataset, title=title)
908 if fig is None:
909 fig = PlotlyFigure(two_yaxis=False)
911 if show_mag:
912 fig.add_plot(model.r, model.chir_mag, label='|sum|')
914 if show_real:
915 fig.add_plot(model.r, model.chir_re, label='Re[sum]')
917 if show_imag:
918 fig.add_plot(model.r, model.chir_re, label='Im[sum]')
920 for ipath in range(len(dataset.pathlist)):
921 path = dataset.pathlist[ipath]
922 label = 'path %i' % (1+ipath)
923 off = (ipath+1)*offset
924 if show_mag:
925 fig.add_plot(path.r, off+path.chir_mag, label=f'|{label}|')
927 if show_real:
928 fig.add_plot(path.r, off+path.chir_re, label=f'Re[{label}]')
930 if show_imag:
931 fig.add_plot(path.r, off+path.chir_im, label=f'Im[{label}]')
933 return fig.show(title=title, xlabel=plotlabels.r,
934 ylabel=chirlab(kweight), xmax=rmax)
936def plot_prepeaks_baseline(dgroup, subtract_baseline=False, show_fitrange=True,
937 show_peakrange=True):
938 """Plot pre-edge peak baseline fit, as from `pre_edge_baseline` or XAS Viewer
940 dgroup must have a 'prepeaks' attribute
941 """
942 if not hasattr(dgroup, 'prepeaks'):
943 raise ValueError('Group needs prepeaks')
944 #endif
945 ppeak = dgroup.prepeaks
947 px0, px1, py0, py1 = extend_plotrange(dgroup.xdat, dgroup.ydat,
948 xmin=ppeak.emin, xmax=ppeak.emax)
950 title = "pre_edge baseline\n %s" % dgroup.filename
952 fig = PlotlyFigure(two_yaxis=False)
954 ydat = dgroup.ydat
955 xdat = dgroup.xdat
956 if subtract_baseline:
957 fig.add_plot(ppeak.energy, ppeak.baseline, label='baseline subtracted peaks')
958 else:
959 fig.add_plot(ppeak.energy, ppeak.baseline, label='baseline')
960 fig.add_plot(xdat, ydat, label='data')
962 if show_fitrange:
963 for x in (ppeak.emin, ppeak.emax):
964 fig.add_vline(x=x, line_width=2, line_dash="dash", line_color="#DDDDCC")
965 fig.add_vline(x=ppeak.centroid, line_width=2, line_dash="dash", line_color="#EECCCC")
967 if show_peakrange:
968 for x in (ppeak.elo, ppeak.ehi):
969 y = ydat[index_of(xdat, x)]
970 fig.add_plot([x], [y], marker='o', marker_size=7)
972 return fig.show(title=title, xlabel=plotlabels.energy, ylabel='mu (normalized)',
973 xmin=px0, xmax=px1, ymin=py0, ymax=py1)
976def plot_prepeaks_fit(dgroup, nfit=0, show_init=False, subtract_baseline=False,
977 show_residual=False):
978 """plot pre-edge peak fit, as from Larix
980 dgroup must have a 'peakfit_history' attribute
981 """
982 if not hasattr(dgroup, 'prepeaks'):
983 raise ValueError('Group needs prepeaks')
984 #endif
985 if show_init:
986 result = pkfit = dgroup.prepeaks
987 else:
988 hist = getattr(dgroup.prepeaks, 'fit_history', None)
989 if nfit > len(hist):
990 nfit = 0
991 pkfit = hist[nfit]
992 result = pkfit.result
993 #endif
995 if pkfit is None:
996 raise ValueError('Group needs prepeaks.fit_history or init_fit')
997 #endif
999 opts = pkfit.user_options
1000 xeps = min(np.diff(dgroup.xdat)) / 5.
1001 xdat = 1.0*pkfit.energy
1002 ydat = 1.0*pkfit.norm
1004 xdat_full = 1.0*dgroup.xdat
1005 ydat_full = 1.0*dgroup.ydat
1007 if show_init:
1008 yfit = pkfit.init_fit
1009 ycomps = None # pkfit.init_ycomps
1010 ylabel = 'model'
1011 else:
1012 yfit = 1.0*result.best_fit
1013 ycomps = pkfit.ycomps
1014 ylabel = 'best fit'
1016 baseline = 0.*ydat
1017 if ycomps is not None:
1018 for label, ycomp in ycomps.items():
1019 if label in opts['bkg_components']:
1020 baseline += ycomp
1022 fig = PlotlyFigure(two_yaxis=False)
1023 title ='%s:\npre-edge peak' % dgroup.filename
1027 if subtract_baseline:
1028 ydat -= baseline
1029 yfit -= baseline
1030 ydat_full = 1.0*ydat
1031 xdat_full = 1.0*xdat
1032 plotopts['ylabel'] = '%s-baseline' % plotopts['ylabel']
1034 dx0, dx1, dy0, dy1 = extend_plotrange(xdat_full, ydat_full,
1035 xmin=opts['emin'], xmax=opts['emax'])
1036 fx0, fx1, fy0, fy1 = extend_plotrange(xdat, yfit,
1037 xmin=opts['emin'], xmax=opts['emax'])
1039 ncolor = 0
1040 popts = {}
1041 plotopts.update(popts)
1042 dymin = dymax = None
1044 fig.add_plot(xdat, ydat, label='data')
1045 fig.add_plot(xday, yfit, label='fit')
1047 if show_residual:
1048 dfig = PlotlyFigure()
1049 dfig.add_plot(xdat, yfit-ydat, label='fit-data')
1050 dy = yfit - ydat
1051 dymax, dymin = dy.max(), dy.min()
1052 dymax += 0.05 * (dymax - dymin)
1053 dymin -= 0.05 * (dymax - dymin)
1055 if ycomps is not None:
1056 ncomps = len(ycomps)
1057 if not subtract_baseline:
1058 fig.add_plot(xdat, baseline, label='baseline')
1059 for icomp, label in enumerate(ycomps):
1060 ycomp = ycomps[label]
1061 if label in opts['bkg_components']:
1062 continue
1063 fig.add_plot(xdat, ycomp, label=label)
1065 if opts.get('show_fitrange', False):
1066 for attr in ('emin', 'emax'):
1067 fig.add_vline(opts[attr], line_width=2, line_dash="dash", line_color="#DDDDCC")
1069 if opts.get('show_centroid', False):
1070 pcen = getattr(dgroup.prepeaks, 'centroid', None)
1071 if hasattr(result, 'params'):
1072 pcen = result.params.get('fit_centroid', None)
1073 if pcen is not None:
1074 pcen = pcen.value
1075 if pcen is not None:
1076 fig.add_vlinee(pcen, color='#EECCCC')
1078 fig.show(title=title, xlabel=plotlabels.energy, ylabel=opts['array_desc'])
1079 dfig.show(title=tile, ylabel='fit-data', ymin=dymin, ymax=dymax)
1080 return fig, dfig
1083def _pca_ncomps(result, min_weight=0, ncomps=None):
1084 if ncomps is None:
1085 if min_weight > 1.e-12:
1086 ncomps = np.where(result.variances < min_weight)[0][0]
1087 else:
1088 ncomps = np.argmin(result.ind)
1089 return ncomps
1092def plot_pca_components(result, min_weight=0, ncomps=None, min_variance=1.e-5):
1093 """Plot components from PCA result
1095 result must be output of `pca_train`
1096 """
1097 title = "PCA components"
1099 ncomps = int(result.nsig)
1100 fig = PlotlyFigure(two_yaxis=False)
1101 fig.add_plot(result.x, result.mean, label='Mean')
1102 for i, comp in enumerate(result.components):
1103 if result.variances[i] > min_variance:
1104 label = 'Comp# %d (%.4f)' % (i+1, result.variances[i])
1105 fig.add_plot(result.x, comp, label=label)
1107 return fig.show(title=title, xlabel=plotlabels.energy, ylabel=plotlabels.norm,
1108 xmin=result.xmin, xmax=result.xmax)
1110def plot_pca_weights(result, min_weight=0, ncomps=None):
1111 """Plot component weights from PCA result (aka SCREE plot)
1113 result must be output of `pca_train`
1114 """
1115 max_comps = len(result.components)-1
1117 title = "PCA Variances (SCREE) and Indicator Values"
1118 fig = PlotlyFigure(two_yaxis=True)
1120 ncomps = max(1, int(result.nsig))
1122 x0, x1, y0, y1 = extend_plotrange(result.variances, result.variances)
1123 y0 = max(1.e-6, min(result.variances[:-1]))
1124 x = 1+np.arange(ncomps)
1125 y = result.variances[:ncomps]
1126 fig.add_plot(x, y, label='significant', style='solid', marker='o')
1128 xe = 1 + np.arange(ncomps-1, max_comps)
1129 ye = result.variances[ncomps-1:ncomps+max_comps]
1131 fig.add_plot(xe, ye, label='not significant', style='dashed', marker='o')
1132 fig.set_ylog()
1133 yi = result.ind[1:]
1134 xi = 1 + np.arange(len(yi))
1136 x0, x1, yimin, yimax = extend_plotrange(xi, yi)
1138 fig.add_plot(xi, result.ind[1:], label='Indicator Value',
1139 style='solid', side='right')
1140 fig.fig.update_yaxes(title_text='Indicator', secondary_y=True)
1141 return fig.show(title=title, xlabel='Component #', ylabel='variance')
1144def plot_pca_fit(dgroup, with_components=True):
1145 """Plot data and fit result from pca_fit, which rom PCA result
1147 result must be output of `pca_fit`
1148 """
1149 title = "PCA fit: %s" % (dgroup.filename)
1150 result = dgroup.pca_result
1151 model = result.pca_model
1153 fig = PlotlyFigure(two_yaxis=False)
1154 fig.add_plot(result.x, result.ydat, label='data')
1155 fig.add_plot(result.x, result.yfit, label='fit')
1156 if with_components:
1157 fig.add_plot(result.x, model.mean, label='mean')
1158 for n in range(len(result.weights)):
1159 cval = model.components[n]*result.weights[n]
1160 fig.add_plot(result.x, cval, label='Comp #%d' % (n+1))
1162 fig.show(title=title, xmin=model.xmin, xmax=model.xmax,
1163 xlabel=plotlabels.energy, ylabel=plotlabels.norm)
1165 dfig = PlotlyFigure(two_yaxis=False)
1166 dfig.add_plot(result.x, result.yfit-result.ydat, label='fit-data')
1167 dfig.show(title=title, xmin=model.xmin, xmax=model.xmax,
1168 xlabel=plotlabels.energy, ylabel='fit-data')
1169 return fig, dfig
1171def plot_diffkk(dgroup, emin=None, emax=None, new=True, label=None,
1172 title=None, offset=0):
1173 """
1174 plot_diffkk(dgroup, norm=True, emin=None, emax=None, show_e0=False, label=None):
1176 Plot mu(E) and background mu0(E) for XAFS data group
1178 Arguments
1179 ----------
1180 dgroup group of XAFS data after autobk() results (see Note 1)
1181 norm bool whether to show normalized data [True]
1182 emin min energy to show, absolute or relative to E0 [None, start of data]
1183 emax max energy to show, absolute or relative to E0 [None, end of data]
1184 show_e0 bool whether to show E0 [False]
1185 label string for label [``None``: 'mu']
1186 title string for plot title [None, may use filename if available]
1187 offset vertical offset to use for y-array [0]
1189 Notes
1190 -----
1191 1. The input data group must have the following attributes:
1192 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
1193 """
1194 if hasattr(dgroup, 'f2'):
1195 f2 = dgroup.f2
1196 else:
1197 raise ValueError("Data group has no array for f2")
1198 #endif
1199 ylabel = r'$f \rm\,\, (e^{-})$ '
1200 emin, emax = _get_erange(dgroup, emin, emax)
1201 title = _get_title(dgroup, title=title)
1203 labels = {'f2': r"$f_2(E)$", 'fpp': r"$f''(E)$", 'fp': r"$f'(E)$", 'f1': r"$f_1(E)$"}
1205 fig = PlotlyFigure(two_yaxis=False)
1206 fig.add_plot(dgroup.energy, f2, label=labels['f2'])
1208 for attr in ('fpp', 'f1', 'fp'):
1209 yval = getattr(dgroup, attr)
1210 if yval is not None:
1211 fig.add_plot(dgroup.energy, yval, label=labels[attr])
1213 return fig.show(title=title, xlabel=plotlabels.energy, yaxis_label=ylabel,
1214 xmin=emin, xmax=emax)
1217def plot_feffdat(feffpath, with_phase=True, title=None, fig=None):
1218 """
1219 plot_feffdat(feffpath, with_phase=True, title=None)
1221 Plot Feff's magnitude and phase as a function of k for a FeffPath
1223 Arguments
1224 ----------
1225 feffpath feff path as read by feffpath()
1226 with_pase whether to plot phase(k) as well as magnitude [True]
1227 title string for plot title [None, may use filename if available]
1229 Notes
1230 -----
1231 1. The input data group must have the following attributes:
1232 energy, mu, bkg, norm, e0, pre_edge, edge_step, filename
1233 """
1234 if hasattr(feffpath, '_feffdat'):
1235 fdat = feffpath._feffdat
1236 else:
1237 raise ValueError("must pass in a Feff path as from feffpath()")
1239 if fig is None:
1240 fig = PlotlyFigure(two_yaxis=True)
1241 fig.add_plot(result.x, result.ydat, label='data')
1244 fig.add_plot(fdat.k, fdat.mag_feff, label='magnitude')
1245 # xlabel=plotlabels.k,
1246 # ylabel='|F(k)|', title=title,
1248 if with_phase:
1249 fig.add_plot(fdat.k, fdat.pha_feff, label='phase')
1250 fig.fig.update_yaxis(title_text='Phase(k)', secondary_y=True)
1251 return fig.show(title=title, xlabel=plotlabels.k, ylabel='|F(k)|')
1253#enddef
1255def plot_wavelet(dgroup, show_mag=True, show_real=False, show_imag=False,
1256 rmax=None, kmax=None, kweight=None, title=None):
1257 """
1258 plot_wavelet(dgroup, show_mag=True, show_real=False, show_imag=False,
1259 rmax=None, kmax=None, kweight=None, title=None)
1261 Plot wavelet for XAFS data group
1263 Arguments
1264 ----------
1265 dgroup group of XAFS data after xftf() results (see Note 1)
1266 show_mag bool whether to plot wavelet magnitude [True]
1267 show_real bool whether to plot real part of wavelet [False]
1268 show_imag bool whether to plot imaginary part of wavelet [False]
1269 title string for plot title [None, may use filename if available]
1270 rmax max R to show [None, end of data]
1271 kmax max k to show [None, end of data]
1272 kweight k-weight to use to construct wavelet [None, take from group]
1274 Notes
1275 -----
1276 The wavelet will be performed
1277 """
1278 print("Image display not yet available with larch+plotly")
1279 kweight = _get_kweight(dgroup, kweight)
1280 cauchy_wavelet(dgroup, kweight=kweight, rmax_out=rmax)
1281 title = _get_title(dgroup, title=title)
1283 opts = dict(title=title, x=dgroup.k, y=dgroup.wcauchy_r, xmax=kmax,
1284 ymax=rmax, xlabel=plotlabels.k, ylabel=plotlabels.r,
1285 show_axis=True)
1286 if show_mag:
1287 _imshow(dgroup.wcauchy_mag, **opts)
1288 elif show_real:
1289 _imshow(dgroup.wcauchy_real, **opts)
1290 elif show_imag:
1291 _imshow(dgroup.wcauchy_imag, **opts)
1292 #endif
1293#enddef