# -*- coding: utf-8 -*-
# Copyright (c) 2015-2022, Exa Analytics Development Team
# Distributed under the terms of the Apache License 2.0
'''
Plotter
#################
This is supposed to be a collection of classes and functions to aid in plotting
'''
from bokeh.plotting import output_notebook, show, figure
from bokeh.models.ranges import Range1d
import numpy as np
[docs]def lorentzian(freq, x, fwhm, inten=None):
'''
Plot lorentzian lineshapes
Args:
freq (np.ndarray): Frequencies where the peaks will be located
x (np.ndarray): X-axis data points
fwhm (float): Full-width at half maximum
inten (np.ndarray): Intensities of the peaks
Returns:
y (np.ndarray): Y values of the lorentzian lineshapes
'''
y = np.zeros(len(x))
if inten is None:
for fdx in freq:
y += 1/(2*np.pi)*fwhm/((fdx-x)**2+(0.5*fwhm)**2)
else:
for fdx, idx in zip(freq, inten):
y += 1/(2*np.pi)*idx*fwhm/((fdx-x)**2+(0.5*fwhm)**2)
return y
[docs]def gaussian(freq, x, fwhm, inten=None):
'''
Plot gaussian lineshapes
Args:
freq (np.ndarray): Frequencies where the peaks will be located
x (np.ndarray): X-axis data points
fwhm (float): Full-width at half maximum
inten (np.ndarray): Intensities of the peaks
Returns:
y (np.ndarray): Y values of the gaussian lineshapes
'''
y = np.zeros(len(x))
sigma = fwhm/(np.sqrt(8*np.log(2)))
if inten is None:
for fdx in freq:
y += 1/(sigma*np.sqrt(2*np.pi))*np.exp(-(x-fdx)**2/(2*sigma**2))
else:
for idx, fdx in zip(inten, freq):
y += 1/(sigma*np.sqrt(2*np.pi))*idx*np.exp(-(x-fdx)**2/(2*sigma**2))
return y
[docs]class Plot:
'''
Class that has a collection of methods to make plotting easier. Some of the bokeh functions
require importing specific functions like 'show' to display the figure. We want to make
this easier by defining methods like show so we can just import the class and it takes
care of everything.
'''
[docs] def show(self):
# method just to have simple show function like in matplotlib
show(self.fig)
[docs] def set_xrange(self, xmin, xmax):
# set the xrange
# makes it simple to flip the xaxis by giving the max value as the
# xmin and the min value as the xmax
self.fig.x_range = Range1d(xmin, xmax)
[docs] def set_yrange(self, ymin, ymax):
# set the yrange
self.fig.y_range = Range1d(ymin, ymax)
def __init__(self, *args, **kwargs):
# this worries me a bit and not sure if this is the proper way to do this
output_notebook()
# set the title
title = kwargs.pop('title', '')
# set the plot area parameters
plot_width = kwargs.pop('plot_width', 500)
plot_height = kwargs.pop('plot_height', 500)
# set the tools to be used
tools = kwargs.pop('tools', 'hover, crosshair, pan, wheel_zoom, box_zoom, reset, save,')
# create the figure
self.fig = figure(title=title, plot_height=plot_height, plot_width=plot_width, tools=tools)
# a matplotlib example
# maybe we can make some conditional so you can use a bokeh plot or a matplotlib plot
# might be useful if we just want to display the plot right on the screen as opposed
# to having the plot on the web browser
#
#import numpy as np
#import matplotlib.pyplot as plt
#from matplotlib import ticker, rc
#
#class Plot:
# def lorentz(freq, x, fwhm, inten=None):
# y = np.zeros(len(x))
# if inten is None:
# for fdx in freq:
# y += 1/(2*np.pi)*fwhm/((fdx-x)**2+(0.5*fwhm)**2)
# else:
# for fdx, idx in zip(freq, inten):
# y += 1/(2*np.pi)*idx*fwhm/((fdx-x)**2+(0.5*fwhm)**2)
# return y
#
# def __init__(self, *args, **kwargs):
# title = kwargs.pop('title', '')
# xlabel = kwargs.pop('xlabel', '')
# ylabel = kwargs.pop('ylabel', '')
# marker = kwargs.pop('marker', '')
# line = kwargs.pop('line', '-')
# figsize = kwargs.pop('figsize', (8,8))
# dpi = kwargs.pop('dpi', 50)
# xrange = kwargs.pop('xrange', None)
# yrange = kwargs.pop('yrange', None)
# fwhm = kwargs.pop('fwhm', 15)
# res = kwargs.pop('res', 1)
# grid = kwargs.pop('grid', False)
# legend = kwargs.pop('legend', True)
# invert_x = kwargs.pop('invert_x', False)
# font = kwargs.pop('font', 10)
# lorentz = kwargs.pop('lorentz', True)
# self.fig = plt.figure(figsize=figsize, dpi=dpi)
# rc('font', size=font)