Compare Bands

Overview

The pyprocar.bandsplot() function is a powerful tool for visualizing electronic band structures. One of its key features is that it returns matplotlib Figure and Axes objects when show=False, which enables advanced plotting capabilities including comparing multiple band structures on the same plot.

What bandsplot returns

When called with show=False, bandsplot() returns:

  • fig: A matplotlib Figure object containing the entire plot

  • ax: A matplotlib Axes object representing the plotting area

Method for comparing band structures

To compare band structures from different codes or calculations:

  1. First call: Use bandsplot() with show=False to generate the initial band structure and capture the fig and ax objects

  2. Subsequent calls: Pass the ax object to additional bandsplot() calls using the ax parameter

  3. Final display: The last call should have show=True to display the combined plot

This approach allows you to overlay multiple band structures from different DFT codes (like VASP and Quantum Espresso) or different calculations on the same axes for direct comparison.

Example: Comparing VASP and Quantum Espresso Band Structures

In this tutorial, we’ll compare Fe band structures calculated with both VASP and Quantum Espresso (QE) codes.

Import libraries and download example data

First, we’ll import the necessary libraries and download the example Fe band structure data for both VASP and Quantum Espresso calculations.

[3]:
# Import required libraries
from pathlib import Path
import pyprocar

CURRENT_DIR = Path(".").resolve()
print(str(CURRENT_DIR))
COMPARE_BANDS_PATH = "data/examples/bands/compare_bands"

pyprocar.download_from_hf(relpath=COMPARE_BANDS_PATH, output_path=CURRENT_DIR)
QE_DATA_DIR = CURRENT_DIR / COMPARE_BANDS_PATH / "qe"
VASP_DATA_DIR = CURRENT_DIR / COMPARE_BANDS_PATH / "vasp"
print(f"Data downloaded to: {QE_DATA_DIR}")
print(f"Data downloaded to: {VASP_DATA_DIR}")
C:\Users\lllang\Desktop\notebooks\Notebook\01 - Projects\Pyprocar\pyprocar\examples\00-band_structure
c:\Users\lllang\miniconda3\envs\pyprocar\lib\site-packages\huggingface_hub\file_download.py:143: UserWarning: `huggingface_hub` cache-system uses symlinks by default to efficiently store duplicated files but your machine does not support them in C:\Users\lllang\.cache\huggingface\hub\datasets--lllangWV--pyprocar_test_data. Caching files will still work but in a degraded version that might require more space on your disk. This warning can be disabled by setting the `HF_HUB_DISABLE_SYMLINKS_WARNING` environment variable. For more details, see https://huggingface.co/docs/huggingface_hub/how-to-cache#limitations.
To support symlinks on Windows, you either need to activate Developer Mode or to run Python as an administrator. In order to activate developer mode, see this article: https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development
  warnings.warn(message)
Data downloaded to: C:\Users\lllang\Desktop\notebooks\Notebook\01 - Projects\Pyprocar\pyprocar\examples\00-band_structure\data\examples\00-band_structure\compare_bands\qe
Data downloaded to: C:\Users\lllang\Desktop\notebooks\Notebook\01 - Projects\Pyprocar\pyprocar\examples\00-band_structure\data\examples\00-band_structure\compare_bands\vasp

Comparing band structures

Now we’ll demonstrate the band comparison technique:

  1. Step 1: Plot the VASP band structure with show=False to capture the fig and ax objects

  2. Step 2: Plot the QE band structure using the same ax object and show=True to display the combined result

The VASP bands will be plotted in parametric mode (showing orbital contributions with colors) while the QE bands will be overlaid in plain mode (black lines) for clear comparison.

[2]:
print(str(VASP_DATA_DIR))
# Step 1: Plot VASP band structure and capture fig, ax objects
fig, ax = pyprocar.bandsplot(
    code="vasp",
    dirname=str(VASP_DATA_DIR),
    mode="parametric",
    fermi=5.3017,  # VASP fermi energy
    elimit=[-5, 5],
    orbitals=[4, 5, 6, 7, 8],  # d orbitals for Fe
    use_cache=False,
    show=False,  # Don't show yet, capture the axes
    quiet_welcome=True,
    verbose=3,
)

# # Step 2: Plot QE band structure on the same axes
pyprocar.bandsplot(
    code="qe",
    dirname=QE_DATA_DIR,
    mode="plain",
    fermi=12.5491,  # QE fermi energy
    elimit=[-5, 5],
    color="k",  # Black lines for QE bands
    ax=ax,  # Use the same axes from VASP plot
    show=True,  # Show the combined plot
    verbose=3,
)
C:\Users\lllang\Desktop\notebooks\Notebook\01 - Projects\Pyprocar\pyprocar\examples\00-band_structure\data\examples\00-band_structure\compare_bands\vasp
If you want more detailed logs, set verbose to 2 or more
____________________________________________________________________________________________________
____________________________________________________________________________________________________
____________________________________________________________________________________________________
WARNING: Not using cache, removing existing cache files
[INFO] 2025-06-11 22:44:54 - pyprocar.scripts.scriptBandsplot[147][bandsplot] - Removing existing structure file: C:\Users\lllang\Desktop\notebooks\Notebook\01 - Projects\Pyprocar\pyprocar\examples\00-band_structure\data\examples\00-band_structure\compare_bands\vasp\structure.pkl
[INFO] 2025-06-11 22:44:54 - pyprocar.scripts.scriptBandsplot[153][bandsplot] - Removing existing EBS file: C:\Users\lllang\Desktop\notebooks\Notebook\01 - Projects\Pyprocar\pyprocar\examples\00-band_structure\data\examples\00-band_structure\compare_bands\vasp\ebs.pkl
[INFO] 2025-06-11 22:44:54 - pyprocar.scripts.scriptBandsplot[157][bandsplot] - Parsing EBS from C:\Users\lllang\Desktop\notebooks\Notebook\01 - Projects\Pyprocar\pyprocar\examples\00-band_structure\data\examples\00-band_structure\compare_bands\vasp
[INFO] 2025-06-11 22:44:54 - pyprocar.io.parser[230][_parse_vasp] - Parsing VASP files in C:\Users\lllang\Desktop\notebooks\Notebook\01 - Projects\Pyprocar\pyprocar\examples\00-band_structure\data\examples\00-band_structure\compare_bands\vasp
[INFO] 2025-06-11 22:44:54 - pyprocar.io.vasp[49][__init__] - Vasp Version: 6.2.1
Parsing KPOINTS file: C:\Users\lllang\Desktop\notebooks\Notebook\01 - Projects\Pyprocar\pyprocar\examples\00-band_structure\data\examples\00-band_structure\compare_bands\vasp\KPOINTS
[INFO] 2025-06-11 22:44:54 - pyprocar.core.ebs[81][__init__] - Initializing the ElectronicBandStructure object
[INFO] 2025-06-11 22:44:54 - pyprocar.core.ebs[154][__init__] - Subtracting Fermi Energy from Bands
[INFO] 2025-06-11 22:44:54 - pyprocar.core.ebs[155][__init__] - Is Mesh: False
[INFO] 2025-06-11 22:44:54 - pyprocar.core.ebs[156][__init__] - Fermi Energy: 4.5746
[INFO] 2025-06-11 22:44:54 - pyprocar.core.ebs[157][__init__] - Kpoints shape: (200, 3)
[INFO] 2025-06-11 22:44:54 - pyprocar.core.ebs[158][__init__] - Bands shape: (200, 20, 1)
[INFO] 2025-06-11 22:44:54 - pyprocar.core.ebs[160][__init__] - Projected shape: (200, 20, 5, 1, 9, 1)
[INFO] 2025-06-11 22:44:54 - pyprocar.core.ebs[164][__init__] - Kpath: K-Path
------
 1. $\Gamma$ : (0.00 0.00 0.00) -> $X$      : (0.00 0.50 0.00)
 2. $X$      : (0.00 0.50 0.00) -> $M$      : (0.50 0.50 0.00)
 3. $M$      : (0.50 0.50 0.00) -> $\Gamma$ : (0.00 0.00 0.00)
 4. $\Gamma$ : (0.00 0.00 0.00) -> $R$      : (0.50 0.50 0.50)
 5. $R$      : (0.50 0.50 0.50) -> $X$      : (0.00 0.50 0.00)

[INFO] 2025-06-11 22:44:54 - pyprocar.core.ebs[166][__init__] - Kpath: ['s', 'py', 'pz', 'px', 'dxy', 'dyz', 'dz2', 'dxz', 'x2-y2']
[INFO] 2025-06-11 22:44:54 - pyprocar.core.ebs[168][__init__] - Reciprocal lattice:
[[0.26 0.   0.  ]
 [0.   0.26 0.  ]
 [0.   0.   0.26]]
[INFO] 2025-06-11 22:44:54 - pyprocar.core.ebs[171][__init__] - Initialized the ElectronicBandStructure object
[DEBUG] 2025-06-11 22:44:54 - pyprocar.io.vasp[156][get_symmetry_operations] - n_spg_operations: 48
[INFO] 2025-06-11 22:44:54 - pyprocar.io.vasp[311][get_symmetry_operations] - No space group operators block found
[INFO] 2025-06-11 22:44:54 - pyprocar.scripts.scriptBandsplot[182][bandsplot] - Shifting Fermi energy to zero: 5.3017
[INFO] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[81][__init__] - ___Initializing EBSPlot___
[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[83][__init__] - Kpath: K-Path
------
 1. $\Gamma$ : (0.00 0.00 0.00) -> $X$      : (0.00 0.50 0.00)
 2. $X$      : (0.00 0.50 0.00) -> $M$      : (0.50 0.50 0.00)
 3. $M$      : (0.50 0.50 0.00) -> $\Gamma$ : (0.00 0.00 0.00)
 4. $\Gamma$ : (0.00 0.00 0.00) -> $R$      : (0.50 0.50 0.50)
 5. $R$      : (0.50 0.50 0.50) -> $X$      : (0.00 0.50 0.00)

[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[84][__init__] - Non-collinear: False
[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[85][__init__] - Spins: range(0, 1)
[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[86][__init__] - Kdirect: True
[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[87][__init__] - Config: BandStructureConfig(plot_type=<PlotType.BAND_STRUCTURE: 'band_structure'>, custom_settings={}, modes=['plain', 'parametric', 'scatter', 'atomic', 'overlay', 'overlay_species', 'overlay_orbitals'], color='black', spin_colors=('blue', 'red'), colorbar_title='Atomic Orbital Projections', colorbar_title_size=15, colorbar_title_padding=20, colorbar_tick_labelsize=10, cmap='jet', clim=(0.0, 1.0), fermi_color='blue', fermi_linestyle='dotted', fermi_linewidth=1, grid=False, grid_axis='both', grid_color='grey', grid_linestyle='solid', grid_linewidth=1, grid_which='major', label=('$\\uparrow$', '$\\downarrow$'), legend=True, linestyle=('solid', 'dashed'), linewidth=(1.0, 1.0), marker=('o', 'v', '^', 'D'), markersize=(0.2, 0.2), opacity=(1.0, 1.0), plot_color_bar=True, savefig=None, title=None, weighted_color=True, weighted_width=False, figure_size=(9, 6), dpi=300, colorbar_tick_params={}, colorbar_label_params={}, x_label='K vector', x_label_params={}, y_label_params={}, title_params={}, major_y_tick_params={'which': 'major', 'axis': 'y', 'direction': 'inout', 'width': 1, 'length': 5, 'labelright': False, 'right': True, 'left': True}, minor_y_tick_params={'which': 'minor', 'axis': 'y', 'direction': 'in', 'left': True, 'right': True}, major_x_tick_params={'which': 'major', 'axis': 'x', 'direction': 'in'}, multiple_locator_y_major_value=None, multiple_locator_y_minor_value=None)
[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[88][__init__] - EBS:
 Electronic Band Structure
============================
Total number of kpoints   = 200
Total number of bands    = 20
Total number of atoms    = 5
Total number of orbitals = 9

Array Shapes:
------------------------
Kpoints shape  = (200, 3)
Bands shape    = (200, 20, 1)
Projected shape = (200, 20, 5, 1, 9, 1)
Kpath = K-Path
------
 1. $\Gamma$ : (0.00 0.00 0.00) -> $X$      : (0.00 0.50 0.00)
 2. $X$      : (0.00 0.50 0.00) -> $M$      : (0.50 0.50 0.00)
 3. $M$      : (0.50 0.50 0.00) -> $\Gamma$ : (0.00 0.00 0.00)
 4. $\Gamma$ : (0.00 0.00 0.00) -> $R$      : (0.50 0.50 0.50)
 5. $R$      : (0.50 0.50 0.50) -> $X$      : (0.00 0.50 0.00)

Labels = ['s', 'py', 'pz', 'px', 'dxy', 'dyz', 'dz2', 'dxz', 'x2-y2']
Reciprocal Lattice =
 [[0.26 0.   0.  ]
 [0.   0.26 0.  ]
 [0.   0.   0.26]]

Additional information:
------------------------
Fermi Energy = 4.5746
Is Mesh = False
Has Phase = False

[INFO] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[116][_get_x] - ___Getting x values___
[INFO] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[146][_get_x] - Kpath exists and nsegments == ngrids. Creating path from kpath
[INFO] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[697][set_xticks] - ___Setting x ticks___
[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[698][set_xticks] - Setting x ticks:
        positions=[0, 39, 79, 119, 159, 199]
        names=['$\\Gamma$', '$X$', '$M$', '$\\Gamma$', '$R$', '$X$']
        color=black
[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[708][set_xticks] - Overriding default tick_positions: [0, 39, 79, 119, 159, 199]
[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[711][set_xticks] - Overriding default tick_names: ['$\\Gamma$', '$X$', '$M$', '$\\Gamma$', '$R$', '$X$']
Plotting bands in parametric mode
[INFO] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[420][plot_parameteric] - ___No mask applied___
[INFO] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[697][set_xticks] - ___Setting x ticks___
[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[698][set_xticks] - Setting x ticks:
        positions=[0, 39, 79, 119, 159, 199]
        names=['$\\Gamma$', '$X$', '$M$', '$\\Gamma$', '$R$', '$X$']
        color=black
[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[708][set_xticks] - Overriding default tick_positions: [0, 39, 79, 119, 159, 199]
[DEBUG] 2025-06-11 22:44:54 - pyprocar.plotter.ebs_plot[711][set_xticks] - Overriding default tick_names: ['$\\Gamma$', '$X$', '$M$', '$\\Gamma$', '$R$', '$X$']
If you want more detailed logs, set verbose to 2 or more
____________________________________________________________________________________________________
 ____        ____
|  _ \ _   _|  _ \ _ __ ___   ___ __ _ _ __
| |_) | | | | |_) | '__/ _ \ / __/ _` | '__|
|  __/| |_| |  __/| | | (_) | (_| (_| | |
|_|    \__, |_|   |_|  \___/ \___\__,_|_|
       |___/
A Python library for electronic structure pre/post-processing.

Version 6.4.6 created on Mar 6th, 2025

Please cite:
- Uthpala Herath, Pedram Tavadze, Xu He, Eric Bousquet, Sobhit Singh, Francisco Muñoz and Aldo Romero.,
  PyProcar: A Python library for electronic structure pre/post-processing.,
  Computer Physics Communications 251, 107080 (2020).

- L. Lang, P. Tavadze, A. Tellez, E. Bousquet, H. Xu, F. Muñoz, N. Vasquez, U. Herath, and A. H. Romero,
  Expanding PyProcar for new features, maintainability, and reliability.,
  Computer Physics Communications 297, 109063 (2024).

Developers:
- Francisco Muñoz
- Aldo Romero
- Sobhit Singh
- Uthpala Herath
- Pedram Tavadze
- Eric Bousquet
- Xu He
- Reese Boucher
- Logan Lang
- Freddy Farah

____________________________________________________________________________________________________

            There are additional plot options that are defined in the configuration file.
            You can change these configurations by passing the keyword argument to the function.
            To print a list of all plot options set `print_plot_opts=True`

            Here is a list modes : plain , parametric , scatter , atomic , overlay , overlay_species , overlay_orbitals

____________________________________________________________________________________________________
[INFO] 2025-06-11 22:44:55 - pyprocar.scripts.scriptBandsplot[167][bandsplot] - Loading EBS, Structure, and Kpath from cached Pickle files in C:\Users\lllang\Desktop\notebooks\Notebook\01 - Projects\Pyprocar\pyprocar\examples\00-band_structure\data\examples\00-band_structure\compare_bands\qe
[INFO] 2025-06-11 22:44:55 - pyprocar.scripts.scriptBandsplot[182][bandsplot] - Shifting Fermi energy to zero: 12.5491
[INFO] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[81][__init__] - ___Initializing EBSPlot___
[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[83][__init__] - Kpath: K-Path
------
 1. $\Gamma$ : (0.00 0.00 0.00) -> $X$      : (0.50 0.00 0.00)
 2. $X$      : (0.50 0.00 0.00) -> $M$      : (0.50 0.50 0.00)
 3. $M$      : (0.50 0.50 0.00) -> $G$      : (0.00 0.00 0.00)
 4. $G$      : (0.00 0.00 0.00) -> $R$      : (0.50 0.50 0.50)
 5. $R$      : (0.50 0.50 0.50) -> $X$      : (0.50 0.00 0.00)

[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[84][__init__] - Non-collinear: False
[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[85][__init__] - Spins: range(0, 1)
[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[86][__init__] - Kdirect: True
[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[87][__init__] - Config: BandStructureConfig(plot_type=<PlotType.BAND_STRUCTURE: 'band_structure'>, custom_settings={}, modes=['plain', 'parametric', 'scatter', 'atomic', 'overlay', 'overlay_species', 'overlay_orbitals'], color='k', spin_colors=('blue', 'red'), colorbar_title='Atomic Orbital Projections', colorbar_title_size=15, colorbar_title_padding=20, colorbar_tick_labelsize=10, cmap='jet', clim=(0.0, 1.0), fermi_color='blue', fermi_linestyle='dotted', fermi_linewidth=1, grid=False, grid_axis='both', grid_color='grey', grid_linestyle='solid', grid_linewidth=1, grid_which='major', label=('$\\uparrow$', '$\\downarrow$'), legend=True, linestyle=('solid', 'dashed'), linewidth=(1.0, 1.0), marker=('o', 'v', '^', 'D'), markersize=(0.2, 0.2), opacity=(1.0, 1.0), plot_color_bar=True, savefig=None, title=None, weighted_color=True, weighted_width=False, figure_size=(9, 6), dpi=300, colorbar_tick_params={}, colorbar_label_params={}, x_label='K vector', x_label_params={}, y_label_params={}, title_params={}, major_y_tick_params={'which': 'major', 'axis': 'y', 'direction': 'inout', 'width': 1, 'length': 5, 'labelright': False, 'right': True, 'left': True}, minor_y_tick_params={'which': 'minor', 'axis': 'y', 'direction': 'in', 'left': True, 'right': True}, major_x_tick_params={'which': 'major', 'axis': 'x', 'direction': 'in'}, multiple_locator_y_major_value=None, multiple_locator_y_minor_value=None)
[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[88][__init__] - EBS:
 Electronic Band Structure
============================
Total number of kpoints   = 151
Total number of bands    = 25
Total number of atoms    = 5
Total number of orbitals = 9

Array Shapes:
------------------------
Kpoints shape  = (151, 3)
Bands shape    = (151, 25, 1)
Projected shape = (151, 25, 5, 1, 9, 1)
Projected phase shape = (151, 25, 5, 1, 9, 1)
Kpath = K-Path
------
 1. $\Gamma$ : (0.00 0.00 0.00) -> $X$      : (0.50 0.00 0.00)
 2. $X$      : (0.50 0.00 0.00) -> $M$      : (0.50 0.50 0.00)
 3. $M$      : (0.50 0.50 0.00) -> $G$      : (0.00 0.00 0.00)
 4. $G$      : (0.00 0.00 0.00) -> $R$      : (0.50 0.50 0.50)
 5. $R$      : (0.50 0.50 0.50) -> $X$      : (0.50 0.00 0.00)

Labels = ['s', 'py', 'pz', 'px', 'dxy', 'dyz', 'dz2', 'dxz', 'dx2']
Reciprocal Lattice =
 [[1.6335 0.     0.    ]
 [0.     1.6335 0.    ]
 [0.     0.     1.6335]]

Additional information:
------------------------
Fermi Energy = 12.5491
Is Mesh = False
Has Phase = True

[INFO] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[116][_get_x] - ___Getting x values___
[INFO] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[146][_get_x] - Kpath exists and nsegments == ngrids. Creating path from kpath
[INFO] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[697][set_xticks] - ___Setting x ticks___
[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[698][set_xticks] - Setting x ticks:
        positions=[0, 30, 60, 90, 120, 150]
        names=['$\\Gamma$', '$X$', '$M$', '$G$', '$R$', '$X$']
        color=black
[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[708][set_xticks] - Overriding default tick_positions: [0, 30, 60, 90, 120, 150]
[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[711][set_xticks] - Overriding default tick_names: ['$\\Gamma$', '$X$', '$M$', '$G$', '$R$', '$X$']
Plotting bands in plain mode
[INFO] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[697][set_xticks] - ___Setting x ticks___
[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[698][set_xticks] - Setting x ticks:
        positions=[0, 30, 60, 90, 120, 150]
        names=['$\\Gamma$', '$X$', '$M$', '$G$', '$R$', '$X$']
        color=black
[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[708][set_xticks] - Overriding default tick_positions: [0, 30, 60, 90, 120, 150]
[DEBUG] 2025-06-11 22:44:55 - pyprocar.plotter.ebs_plot[711][set_xticks] - Overriding default tick_names: ['$\\Gamma$', '$X$', '$M$', '$G$', '$R$', '$X$']
../../_images/examples_00-band_structure_02-Comparing_Bands_4_1.png
[2]:
(<Figure size 900x600 with 2 Axes>,
 <Axes: xlabel='K vector', ylabel='E - E$_F$ (eV)'>)