Passing Large Number of Arguments as a Dictionary
- Let's take example of
splot_bands
. It requires a lot of arguments and most of them are default, but in order to tweak parameters, you still need to access them. Follow These steps to input arguments easily. - In code cell, write
splot_bands?
and hit enter. This will give Signature and DocString. - Copy arguments and pass to a dictionary
dict(what you copied)
. In a Jupyter Notebook cell, you can edit it:
arg_dict=dict(
path_evr=None,
ax=None,
skipk=None,
kseg_inds=[],
elim=[],
ktick_inds=[],
ktick_vals=[],
Fermi=None
)
arg_dict
- As you can see, I deleted few unnecessary arguments. Now you can use dictionary unpacking operator
**
inside function, it will pass all arguments present in dictionary. Make sure you do not change name of variables, although you can delete as few of them. - Usage: Call function as
splot_bands(**arg_dict)
, it is usful if you run a function with same arguments many times.
Tweaking get_axes
by using gridspec
.
- This is a powerful way yo include any type of grid. For this, first use
gs = axs[0,0].get_gridspec()
and then remove axes you want to replace for another shape, then add required axis byplt.gcf().add_subplot(gs[x_ind, y_ind])
. This process is illustrated in below examples. - Examples
- Axes remain same, just widths and height ratios are chnaged.
import pivotpy.splots as sp
axs = sp.get_axes(figsize=(3.4,2.6),ncols=3,widths=[3.4,1,3.4],nrows=3,heights=[2.6,1,2.6],wspace=0.076,hspace=0.1)
[sp.modify_axes(ax=ax,xticks=[0],yticks=[0]) for ax in axs.ravel()]
[sp.add_colorbar(ax=ax,ticks=[]) for ax in [axs[1,0],axs[1,2]]];
_ = [sp.add_colorbar(ax=ax,vertical=True,ticks=[]) for ax in [axs[0,1],axs[2,1]]]
_ = append_axes(axs[0,2],sharey=True,sharex=True)
- Here we will join two axes and regenerate new axes based on our grid choice.
axs=get_axes(figsize=(5,3.4),nrows=3,ncols=2,widths=[1,1],heights=[1,7,7],wspace=0.4,hspace=0.4,axes_off=[(2,0)],sharex=True,sharey=True)
import pivotpy.splots as sp
import matplotlib.pyplot as plt
axlarge = sp.join_axes(axs[0,0],axs[0,1])
axv = sp.join_axes(axs[1,1],axs[2,1])
sp.add_colorbar(ax=axv,cax=axlarge,vertical=False,cmap_or_clist='RGB')
sp.add_text(ax=axs[1,0],txts='axis[1,0]',xs=0.25,ys=0.5)
sp.add_text(ax=axs[2,0],txts='axis[2,0] is off',xs=0.15,ys=0.5)
import pivotpy.parser as vp
vr=vp.export_vasprun(path='E:/Research/graphene_example/ISPIN_1/bands/vasprun.xml')
sp.splot_bands(path_evr=vr,ax=axv,txt='Plotting',Fermi=-3,ktick_inds=[0,15,30],ktick_vals=['A','B','C'])
sp.add_text(ax=axv,txts='BigAxes',xs=0.25,ys=0.5)
modify_axes(axv,vlines=True,ylim=[-5,5])
- A minial example below shows deleting an axes and then adding a 3D axes with same dimensions.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import pivotpy as pp
ax = get_axes(nrows=2,ncols=2,widths=[1,2],heights=[1,2],axes_3d=[(1,1)])
Broken Axes Plots
Sometimes we need to display different ranges of data scattered far apart. Use fubction break_spines
defined below and see an example.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0,30,50)
y = x**2*np.abs(np.cos(x))
a1, a2 = get_axes(nrows=2)
a1.plot(x,y)
a2.plot(x,y)
# Set limits of data same as height_ratios to make visual correct
a2.set_ylim([0,100])
a1.set_ylim([400,800])
plt.subplots_adjust(hspace=0.12)
break_spines(a1,'bottom','~',rotation=35)
break_spines(a2,['top'],'~',rotation=35)
_ = a1.set_title('$f(x) = x^2|\cos(x)|$')
Example: Graphene
Working in object-oriented way, we can have plenty of options in matplotlib. See the examples below for splot_bands
, which provides an overview of flexibility of matplotlib. All functions are defined in object-oriented way for better compatibility and flexibility.
import matplotlib.pyplot as plt
import pivotpy.parser as vp
import pivotpy.splots as sp
vr1 = vp.export_vasprun(path = f1)
vr2 = vp.export_vasprun(path = f2)
ax0, ax1, ax2 = sp.get_axes(ncols=3,figsize=(8,2.6),sharey=True, sharex=True)
splot_bands(vr1, ax = ax0,color='k',color_='c',lw_ = 0.7,ls_='dashed',elim=[-20,18])
# elim above sets grid automatically, for others, we set later.
splot_bands(vr2,ax=ax1,color='y', ktick_inds=[0,30,60,-1], ktick_vals='ΓMKΓ') #,ktick_vals=['Γ','M','K','Γ'])
splot_bands(vr1, ax=ax2,color='y',label='Unpolarized',lw=3)
splot_bands(vr2, ax=ax2,color='b',color_ = 'w',lw_ = 0.5, ls_ = 'dashed',label=r'$S_\uparrow$',label_ = r'$S_\downarrow$')
ax1.set_ylabel('')
ax2.set_ylabel('')
ax1.grid(axis='x')
ax2.grid(axis='x',ls='dashed')
plt.subplots_adjust(hspace=0.01,wspace=0.05)
import pivotpy.splots as sp
ax = splot_bands(path_evr=f2,elim=[-5,5],ktick_inds=[0,30,60,-1],ktick_vals=['W','K','',''],txt='Graphene',ctxt='r',color='r',color_='k',lw_=0.5,label='Up',label_ = 'Down')
add_text(ax=ax,xs=[0.35,0.5],ys=[0.55,0.7],txts=[r'$E_{gap}$ = 0 eV','edge states'],colors=['red','blue'],fontsize=15)
import pivotpy.splots as sp
import matplotlib.pyplot as plt
plt.style.use('default')
ax = sp.get_axes(ncols=2,figsize=(4,2))
add_colorbar(ax[0],cmap_or_clist='RGB',vertical=False,N=3)
add_colorbar(ax=ax[1],cmap_or_clist=['r','g','b',4],ticklabels=['AAAA','B',"C"],N=15,tickloc='right')
plt.tight_layout()
color_wheel(xy=(0.5,0.5),scale=0.5,colormap='hsv',ticks=[0,1/3,2/3],labels=['Red','Green','Blue'],showlegend=False)
- Below are two functions
splot_rgb_lines
andsplot_color_lines
. The difference between the two is thatsplot_rgb_lines
works with threeelemenents
only and generates a single variable color and variable thickness line, whilesplot_color_lines
plots single colored as many lines as len(elements) with variable thickness.
ax = plt.axes()
for loc, cmap in zip([(0.6,0.1),(0.6,0.6),(0.1,0.6),(0.1,0.1)],['RGB','jet','viridis','coolwarm']):
cax = color_cube(ax,cmap,loc=loc,size=0.3,color='red',N=4)
cax.set_title(cmap)
- splot_rgb_lines() requires lists for
orbs
,labels
, andelements
each of length 3 which will be plotted on one axes.- If you do not provide any arguemnts, this will create graph of s, p,d orbital of the system.
elements
argument is special, you can pass index of element which will pick all ions of that type, or list(length=3) of indices of ions, e.g inelements=[0,[0,1],2]
of system Ga32
As31
Bi1
, 0 and 2 pick all ions of Ga and Bi respectively, while [0,1] will pick first two ions of Ga.- Instead of
elements
,orbs
,labels
, you can usequery_data = {'label: [elements list, orbs list],...}
. - Use good colormaps that have rich variety of colors like
jet, brg,...
.
import os
import numpy as np
import pivotpy as pp
import matplotlib.pyplot as plt
with pp.set_dir('E:/Research/graphene_example/ISPIN_2/bands'):
vr = pp.Vasprun()
#plt.style.use('ggplot')
args_dict = dict(path_evr=vr.data,xytxt=(0.3,0.9),elim=[-20,18])
axs=get_axes(nrows=2,ncols=3,figsize=(9,5),sharex=True,sharey=True)
ax = splot_rgb_lines(ax=axs[0,0],**args_dict,N =3, scale_data=False,spin='up',txt='scale_data=False',colorbar=False,colormap='RGB')
ccax = ax.color_cube(loc=(0.55,0.6),size=0.5)
pos = ccax.get_position() # Relocate color-cube
ccax.set_position([pos.x0*1.29,pos.y0*0.9,pos.width*0.5,pos.height])
args_dict['query_data'] = {'s':[range(2),[0]],'p$_z$':[range(2),[2]],'p$_x$+p$_y$':[range(2),[1,3]]}
splot_rgb_lines(ax=axs[0,1],**args_dict,spin='up',txt='colormap = "summer"\nNot good',colormap = 'summer')
#plt.style.use(['default','seaborn'])
_ = splot_rgb_lines(ax=axs[1,0],**args_dict,spin='up',txt='colormap = "viridis"',colormap = 'viridis')
_ = splot_rgb_lines(ax=axs[1,1],**args_dict,N = 20, spin='up',txt='colormap = "jet"',colormap = 'jet')
ax_s = splot_rgb_lines(vr.data, ax=axs[0,2],spin='up',N = 3,query_data={'s':[[0],[0]]},max_width=12,txt='max_width=12',elim=[-20,18],colorbar=False)
cax = ax_s.add_colorbar(vertical=False)
cax.text(1,0.5,r' $s_ \uparrow$',ha='left',va='center',fontsize=12)
last_ax = splot_rgb_lines(vr.data, ax=axs[1,2],spin='up',query_data={'s':[[0],[0]],'p':[[0],[1,2,3]]},ktick_inds=[0,30,60,-1],ktick_vals='GMKG')
last_ax.grid(axis='x')
- splot_color_lines() requires equal length lists for
orbs
,labels
, andelements
either with one axis or mutltiple axes of same length asorbs
.- If you do not provide any arguemnts, this will plots-orbital of first ion.
elements
argument is special, you can pass index of element which will pick all ions of that type, or list of indices of ions, e.g inelements=[0,[0,1],2]
of system Ga32
As31
Bi1
, 0 and 2 pick all ions of Ga and Bi respectively, while [0,1] will pick first two ions of Ga.- Instead of
elements
,orbs
,labels
, you can usequery_data = {'label: [elements list, orbs list],...}
. - If your given
len(axis)=1
, all projections are plotted on single axis and you can tweak plot aesthetics, legend display etc. There are plenty of options. - If a label is empty i.e. '', it will not show up in legend.
Colors Selection
Instead of giving custom colors, you can use matplotlib's colormaps to be consistent. Use
plt.colormaps()
to see list of available color maps. To get a color array from a map, you can do the following:
from matplotlib.pyplot import cm
colors = cm.hsv(np.linspace(0,1,3))
# This will give you three colors from 'hsv' map.
You can create your own colormap by a list of colors
import pivotpy as pp
cm = pp.create_colormap('RB',['r','b])
cm(0.5) #will give you magenta color between red and blue
Note:A custom colormaps
RGB
is registered in session when you import pivotpy, which could be used when plotting DOS with bands of same color.
import os
path='E:/Research/graphene_example/ISPIN_2/bands'
os.chdir(path)
import pivotpy
import importlib as imp
pp = imp.reload(pivotpy)
import matplotlib.pyplot as plt
axs = pp.get_axes(nrows=2,ncols=3,figsize=(7,5),sharey=True,sharex=True)
args_dict=dict(elements=[0,0,[0,1]],orbs=[0,1,[2]],labels=['s','$p_z$','$p_x$'],
hspace=0.1,wspace=0.07,showlegend=True,elim=[-20,18],
ktick_inds=[0,30,60,-1], ktick_vals=['$\Gamma$','M','K','$\Gamma$'],)
splot_color_lines(axes=axs[0,0],**args_dict,left=0.06,colormap='flag',spin='up');
splot_color_lines(axes=axs[0,1],**args_dict,left=0.06,colormap='Something',spin='down',scale_data=True);
splot_color_lines(axes=axs[0,2],**args_dict,left=0.06,colormap='RGB',spin='both',query_data={'p':[[0,1],[1,2,3]]})
args_dict['showlegend'] = False
splot_color_lines(axes=axs[1,:],**args_dict,left=0.06,colormap='flag',spin='up',xytxt=(0.1,0.9));
axs[0,2].add_text(0.5,1,'query_data takes preference \nover elements, orbs and labels')
- Providing labels while using
_collect_dos
is important, it will automatically return spin up/down saymbols.
ax = splot_dos_lines(path_evr='E:/Research/graphene_example/ISPIN_2/dos/vasprun.xml',
vertical=False,fill_area=True,showlegend=True,include_dos='pdos',linewidth=1,
orbs=[[1,2,3],0,1],elements=[[0],0,[1]],labels=['p','s','Ion1-pz'],
colormap='RGB',elim=[-5,5],spin='both')
High Display Image in Notebook
The function below plt2html
is implemented for use in pivotpy-dash
app to view and save SVG image directly from web app's interface. This also enables high display output in jupyter notebook.
import pivotpy as pp
import matplotlib.pyplot as plt
pp.Vasprun("E:/Research/graphene_example/ISPIN_1/bands/vasprun.xml",elim=[-9,9]).splot_bands()
fig = plt2html(dash_html=None,transparent=False)
fig
Below code snippest could be used to inclue svg in html document from a figure.
data = plt2html(dash_html=False)
html_str= """
<!DOCTYPE html>
<head></head>
<body>
<div>
{}
</div>
</body>
""".format(data)
with open('fig.html','w') as f:
f.write(html_str)