I'm trying to create a HOMO-LUMO diagram for a presentation, similar to the below figure from ResearchGate. I would like to learn how to do this with Python if possible, since I know this language (though I'm a beginner). Is there any easy way to make such an image in Python?
-
2$\begingroup$ I suspect this was a composite image, where presumably just the the red/blue line markers and the Y-axis (along with maybe the energy labels next to the markers) were added programmatically, while the rest of the figure (the molecule images, the molecule labels underneath, the HOMO/LUMO/Eg labels) were added in manually with a simple image editing program like Paint or SmartArt on Windows. For the basic figure, you could probably adapt it from code such as github.com/giacomomarchioro/PyEnergyDiagrams. It would be useful to know where you are stuck currently with making your figure. $\endgroup$– Tyberius ♦Apr 10 at 14:58
-
$\begingroup$ Ideally the "Show more" button in the image would be removed. $\endgroup$– Nike DattaniApr 10 at 15:16
-
1$\begingroup$ Here is an article which clearly explains how to calculate eLumo and eHomo using rdkit and python. andersle.no/posts/2022/mo/mo.html $\endgroup$– Vandan RevanurApr 10 at 15:51
1 Answer
The e_Lumo and e_Homo can be calculated using pyscf and scipy. I will demonstrate using a simple molecule such as ethanol:
Code:
Helper functions and init:
from pyscf import gto, scf, lo, tools
from scipy.constants import physical_constants
HARTREE_TO_EV_FACTOR = dict(physical_constants)['Hartree energy in eV'][0]
def find_homo_lumo(mf):
lumo = float("inf")
lumo_idx = None
homo = -float("inf")
homo_idx = None
for i, (energy, occ) in enumerate(zip(mf.mo_energy, mf.mo_occ)):
if occ > 0 and energy > homo:
homo = energy
homo_idx = i
if occ == 0 and energy < lumo:
lumo = energy
lumo_idx = i
return homo, lumo
basis="sto-3g"
xyz = '''
C -0.887089 0.175064 -0.012535
C 0.460489 -0.515516 -0.046535
O 1.442965 0.307267 0.565572
H -0.847478 1.127768 -0.550817
H -1.658782 -0.453327 -0.465842
H -1.176944 0.403676 1.018306
H 0.768712 -0.724328 -1.075460
H 0.419486 -1.462073 0.500177
H 1.478640 1.141468 0.067135
'''
Main Code:
mol = gto.M(atom=xyz,basis=basis)
mol.build()
mf = scf.RHF(mol).run()
homo_hartree, lumo_hartree = find_homo_lumo(mf)
homo_eV = homo_hartree*HARTREE_TO_EV_FACTOR
lumo_eV = lumo_hartree*HARTREE_TO_EV_FACTOR
Eg = abs(homo_eV - lumo_eV)
So once you have the e_homo, e_lumo and Eg, you can use any image editing software to construct images like the ones in the question.