I am using ASE (Atomic Simulation Environment) for theoretical chemistry and I see an option to plot the irreducible Brillouin zone and this bandpath but I can't figure out how. I'm not a programmer.

My code is:

from ase.io import read

atoms = read(sys.argv[1])

bandpath = atoms.cell.bandpath()


The previous lines in the script work fine, it is the last line (with the plot) that doesn't.

I opened the ASE.dft.kpoints file and found the function inside of class bandpath, plus it is mentioned in the ASE documentation Brillouin zone sampling but I can't figure out what are the self and the **plotkwargs arguments in the definition (def plot(self, **plotkwargs):).

Is it possible to plot the Brillouin zone with this function and how ? Is there another way to get this kind of plot from ASE ?

Best Regards, Dobromir

  • $\begingroup$ In theory you should be able to get the plot by bandpath.plot(). Can you clarify what is the error that you are getting? $\endgroup$
    – Shaun Han
    Dec 16, 2023 at 23:24
  • $\begingroup$ The is no error given, the script simply finishes execution with no messages. $\endgroup$
    – Samaray
    Dec 17, 2023 at 18:37

2 Answers 2


Since you have not provided the XYZ file that you are using to get the atoms I will demonstrate how to plot the bandpath using a simple water molecule.

Here is a sample code to get the bandpath plot.

from ase import Atoms
from ase.io import read

def main():
    # Hardcoded XYZ file content
    xyz_content = """3
    XYZ file example
    H  0.0  0.0  0.0
    O  0.0  0.0  1.0
    H  0.0  1.0  0.0

    # Create a temporary file and write the XYZ content to it
    with open('temp.xyz', 'w') as f:

        # Use the read function to read the atomic structure from the temporary file
        atoms = read('temp.xyz')

        # Set periodic boundary conditions and cell vectors explicitly
        atoms.set_cell([[10.0, 0.0, 0.0],
                        [0.0, 10.0, 0.0],
                        [0.0, 0.0, 10.0]])

        # Print some information about the read structure
        print("Number of atoms:", len(atoms))
        print("Cell vectors:")
        print("Atomic positions:")

        # Calculate and print bandpath information
        bandpath = atoms.cell.bandpath()
        print("Special points:")


    except Exception as e:
        print(f"Error: {e}")
        # Remove the temporary file
        import os

if __name__ == "__main__":

This gives the plot:

enter image description here

And prints out details like:

Number of atoms: 3
Cell vectors:
Cell([10.0, 10.0, 10.0])
Atomic positions:
[[0. 0. 0.]
 [0. 0. 1.]
 [0. 1. 0.]]
BandPath(path='GXMGRX,MR', cell=[3x3], special_points={GMRX}, kpts=[12x3])
Special points:
{'G': array([0., 0., 0.]), 'M': array([0.5, 0.5, 0. ]), 'R': array([0.5, 0.5, 0.5]), 'X': array([0. , 0.5, 0. ])}

So there are a couple of things for you to check:

  1. Check if your input file which you use to build the atoms is valid (Ex. XYZ file)
  2. Check if you get any error traceback when you do the plotting and then debug from there.
  • $\begingroup$ When I execute your code there is no plot and no error message. The information was printed, as expected, I get the same output. I did try with both extended .xyz files and .pdb files which include the cell information. I searched for a possible image being created in the directory but there is none. $\endgroup$
    – Samaray
    Dec 17, 2023 at 18:42
  • 1
    $\begingroup$ It appears that your matplotlib backend is not setup properly. Perhaps this link could help you: matplotlib-backend-setup $\endgroup$ Dec 18, 2023 at 8:09
  • $\begingroup$ I tried, as suggested in the link, import matplotlib ... matplotlib.use('backend') print(matplotlib.get_backend()) bandpath.plot() but with agg, qtagg, gtk3agg and gtk4agg there is no plot, nofile and no error, with wxagg and qtagg there were errors (link missing required files). $\endgroup$
    – Samaray
    Dec 18, 2023 at 17:29

I figured it out by browsing ase.dft.kpoints.py and ase.dft.bz.py The plot(...) function in kpoints.py returns bz.bz_plot(...) object and def bz_plot(...) has an argument show which is False by default and at the end of its definition there is an if show: statement which invokes plt.show(), so basically the code is:

import sys
from ase.io import read

atoms = read(sys.argv[1])
bandpath = atoms.cell.bandpath()

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .