Molecular Orbital Diagrams in LaTeX: TikZ, chemfig and modiagram

A molecular orbital (MO) diagram shows how the atomic orbitals of two atoms combine into the orbitals of a molecule, and where the electrons go. It predicts bond order, bond strength and magnetism, including facts a Lewis structure gets wrong, such as O2 being paramagnetic. The first half of this guide explains how to read and fill an MO diagram, with worked diagrams for H2, O2, N2 and CO. The second half shows how to draw them in LaTeX with the modiagram package, in plain TikZ, and with chemfig and mhchem for the structures and formulas beside them.

How to Read a Molecular Orbital Diagram

Energy runs upward. The atomic orbitals (AOs) of the two atoms are drawn as short horizontal lines on the left and right; the molecular orbitals (MOs) they form sit in the middle, joined to their parent AOs by thin correlation lines. Each pair of AOs that overlaps gives two MOs:

  • a bonding orbital (σ or π), lower in energy than the AOs, where the wavefunctions add and electron density builds up between the nuclei;
  • an antibonding orbital (σ* or π*), higher in energy, with a node between the nuclei.

σ orbitals come from head-on overlap (s with s, or pz with pz along the bond axis); π orbitals come from sideways overlap of px and py, so they come in degenerate pairs. The electrons are then filled in exactly as for atoms: lowest orbital first (Aufbau), at most two per orbital with opposite spins (Pauli), and one electron in each degenerate orbital before pairing (Hund). The result is read off with one formula:

bond order = (electrons in bonding MOs − electrons in antibonding MOs) / 2

Bond order 1 is a single bond, 2 a double bond, 3 a triple bond, 0 means the molecule does not form. Fractional values are allowed and show up in ions. If any MO holds unpaired electrons the species is paramagnetic; if all are paired it is diamagnetic.

H2: The Simplest Diagram

Each hydrogen brings one 1s electron. The two 1s AOs combine into σ1s (bonding) and σ*1s (antibonding). Both electrons go into σ1s with paired spins:

H2:   (σ1s)²           bond order = (2 − 0)/2 = 1,  diamagnetic
He2:  (σ1s)² (σ*1s)²   bond order = (2 − 2)/2 = 0,  no bond
He2+: (σ1s)² (σ*1s)¹   bond order = (2 − 1)/2 = ½,  observed as a weak ion

The same diagram explains why helium is monatomic: in He2 the two extra electrons fill the antibonding orbital and cancel the bonding ones.

Second-Period Diatomics: O2 and N2

For Li2 to Ne2 the 1s electrons are core and are left out. The 2s AOs give σ2s and σ*2s; the three 2p AOs give σ2p, a degenerate π2p pair, a degenerate π*2p pair and σ*2p. There are two orderings of the 2p-derived levels, and this is the point most students lose marks on:

  • O2, F2, Ne2: σ2s < σ*2s < σ2p < π2p < π*2p < σ*2p
  • Li2 to N2: σ2s < σ*2s < π2p < σ2p < π*2p < σ*2p

The difference is s–p mixing. In the lighter atoms the 2s and 2p orbitals are close in energy, so σ2s and σ2p (which have the same symmetry) interact: σ2s is pushed down and σ2p is pushed up, above the π2p pair. From oxygen onwards the 2s–2p gap is too large for the mixing to matter and σ2p drops back below π2p.

O2: bond order 2 and paramagnetic

Oxygen has six valence electrons, so O2 has twelve to place. Fill in order: σ2s (2), σ*2s (2), σ2p (2), π2p (4). Two electrons are left for the two degenerate π*2p orbitals, and Hund's rule puts one in each with parallel spins:

O2:  (σ2s)² (σ*2s)² (σ2p)² (π2p)⁴ (π*2p)¹(π*2p)¹
     bonding = 2 + 2 + 4 = 8,  antibonding = 2 + 2 = 4
     bond order = (8 − 4)/2 = 2        two unpaired electrons → paramagnetic

The Lewis structure O=O has every electron paired and predicts a diamagnetic molecule; liquid oxygen is in fact held between the poles of a magnet. This is the classic success of MO theory. The ions follow immediately: O2+ loses a π* electron (bond order 2.5, shorter bond), superoxide O2− gains one (1.5) and peroxide O22− gains two (1.0, diamagnetic).

N2: bond order 3

Nitrogen has five valence electrons, ten in total for N2, and the mixed ordering applies: σ2s (2), σ*2s (2), π2p (4), σ2p (2). Nothing reaches the antibonding 2p levels:

N2:  (σ2s)² (σ*2s)² (π2p)⁴ (σ2p)²
     bond order = (8 − 2)/2 = 3        all paired → diamagnetic
     HOMO = σ2p (not π2p), confirmed by photoelectron spectroscopy

Both orderings give bond order 3 for N2, but only the mixed one gets the highest occupied orbital right, which matters for ionisation energies and for how N2 binds to metals. B2 is the other tell-tale case: with the mixed ordering its two 2p electrons go one each into the π2p pair, so B2 is paramagnetic, as observed; the unmixed ordering would wrongly pair them in σ2p.

MoleculeValence e−ConfigurationBond orderMagnetism
H22(σ1s)²1diamagnetic
He24(σ1s)²(σ*1s)²0–
Li22(σ2s)²1diamagnetic
Be24(σ2s)²(σ*2s)²0–
B26(σ2s)²(σ*2s)²(π2p)²1paramagnetic
C28(σ2s)²(σ*2s)²(π2p)⁴2diamagnetic
N210(σ2s)²(σ*2s)²(π2p)⁴(σ2p)²3diamagnetic
O212(σ2s)²(σ*2s)²(σ2p)²(π2p)⁴(π*2p)²2paramagnetic
F214(σ2s)²(σ*2s)²(σ2p)²(π2p)⁴(π*2p)⁴1diamagnetic
Ne216…(π*2p)⁴(σ*2p)²0–

Heteronuclear Diatomics: CO and NO

When the two atoms differ, their AOs start at different energies: the more electronegative atom (O in CO) has lower-lying orbitals and is drawn lower on its side. The MOs are no longer symmetric combinations. Each bonding MO lies closer in energy to the lower AO and has more of its character, each antibonding MO is closer to the higher AO. CO has ten valence electrons, the same as N2, and the same mixed ordering, so its bond order is 3. Its bonding orbitals are mostly oxygen in character, while the HOMO (the σ orbital at the top of the filled set) is concentrated on carbon as a lone pair, which is why CO binds to metals through the carbon atom. NO has eleven electrons, one of them in π*: bond order 2.5 and paramagnetic, and losing it to form NO+ strengthens the bond to order 3.

Drawing MO Diagrams with the modiagram Package

modiagram (CTAN, by Clemens Niederberger) draws the whole diagram from a description of the orbitals. It loads TikZ, expl3 and chemgreek itself. Inside the modiagram environment, \atom places the AOs of the left or right atom, \molecule places the MOs, and \EnergyAxis adds the arrow. Each orbital is given as {energy;electrons}, where the energy is a height in centimetres and the electrons are up, down or pair:

\documentclass{article}
\usepackage{modiagram}

\begin{document}
\begin{modiagram}[names, labels]
  \atom[H]{left}{1s = {0;up}}
  \atom[H]{right}{1s = {0;up}}
  \molecule[H$_2$]{1sMO = {0.75;pair}}
  \EnergyAxis
\end{modiagram}
\end{document}

For a molecular orbital the number is the splitting: 1sMO = {0.75;pair} puts σ1s 0.75 cm below the lower 1s AO and σ*1s 0.75 cm above the higher one, and fills σ with a pair. A second electron specification after a comma fills σ*: 1sMO = {0.75;pair,pair} is He2. The names option prints the atom and molecule names from the optional arguments, labels writes 1s, σs and so on under each level, and the correlation lines are drawn automatically.

O2 with modiagram

The 2p AOs take three electron specifications (px, py, pz). The 2pMO key takes two energies, the σ splitting and the π splitting, then six electron slots in the order σ, πy, πz, π*y, π*z, σ*. modiagram takes x as the bond axis, so its labels read 2σx, 2πy and 2πz rather than σ2p. A larger σ splitting than π splitting puts σ2p below π2p, which is the oxygen ordering:

\begin{modiagram}[names, labels]
  \atom[O]{left}{2s = {0;pair}, 2p = {4;pair,up,up}}
  \atom[O]{right}{2s = {0;pair}, 2p = {4;pair,up,up}}
  \molecule[O$_2$]{
    2sMO = {0.8;pair,pair},
    2pMO = {1.8,0.9;pair,pair,pair,up,up}   % σ, πy, πz, πy*, πz*, (σ* empty)
  }
  \EnergyAxis
\end{modiagram}

Trailing empty slots may be left out, so the two up electrons land in π*y and π*z and σ*2p stays empty: exactly the paramagnetic configuration above.

N2 and the mixed ordering

To put π2p below σ2p while keeping σ*2p on top, give the bonding and antibonding splittings separately with a slash:

\begin{modiagram}[names, labels]
  \atom[N]{left}{2s = {0;pair}, 2p = {4;up,up,up}}
  \atom[N]{right}{2s = {0;pair}, 2p = {4;up,up,up}}
  \molecule[N$_2$]{
    2sMO = {0.8;pair,pair},
    2pMO = {0.6/2.2, 1.4/1.6;pair,pair,pair}   % σ/σ*, π/π* splittings
  }
  \EnergyAxis
\end{modiagram}

Here σ2p is 0.6 cm below the 2p level and π2p 1.4 cm below, so π comes first; σ*2p is 2.2 cm above and π*2p 1.6 cm above, so σ* is highest. The three pairs fill σ, πy and πz: ten electrons, bond order 3.

A heteronuclear diagram: CO

Give the two atoms different AO energies. modiagram measures each bonding MO down from the lower of the two AOs and each antibonding MO up from the higher one, which is the correct qualitative picture:

\begin{modiagram}[names, labels]
  \atom[C]{left}{2s = {0.8;pair}, 2p = {4.8;up,up}}
  \atom[O]{right}{2s = {0;pair}, 2p = {3.8;pair,up,up}}
  \molecule[CO]{
    2sMO = {0.6;pair,pair},
    2pMO = {0.7/2.0, 1.3/1.6;pair,pair,pair}
  }
  \EnergyAxis[title]
\end{modiagram}

Options worth knowing

Option / commandEffect
style=plain|square|circle|round|fancyHow the levels are drawn (default plain: a line)
names, labelsShow atom/molecule names and orbital labels
labels-fs=\footnotesizeFont size of the orbital labels
distance=5cmHorizontal distance between the two atoms (default 4 cm)
AO-width=14ptWidth of each level line
color={2piy*=red, 2piz*=red} (inside \molecule)Colour the electrons of named orbitals
\EnergyAxis[title], \EnergyAxis[title=E]Axis with a caption at the top
\setmodiagram{style=square, AO-width=12pt}Set options for every diagram in the document
\AO{s}{0;pair}, \connect{AO1 & 2piy}Add an arbitrary orbital and draw a line between two named orbital nodes

The orbital node names used by color and \connect are 1sleft, 2pzright, 1sigma, 1sigma*, 2sigma, 2psigma, 2piy, 2piz* and so on. The package only knows 1s, 2s and 2p; for d orbitals or a ligand field diagram you need TikZ. Older documents use \begin{MOdiagram} with a capital MO: it still works but prints a deprecation warning, and \MOsetup has become \setmodiagram.

A Pure TikZ Molecular Orbital Diagram

Drawing the diagram directly in TikZ gives full control: each level is a short thick line, each electron a \uparrow or \downarrow node on it, and the correlation lines are dashed. Styles defined once in the picture options keep it tidy. This is the O2 diagram again, with mhchem for the formulas:

\documentclass{standalone}
\usepackage{tikz}
\usepackage[version=4]{mhchem}

\begin{document}
\begin{tikzpicture}[
  level/.style={very thick},
  corr/.style={gray, dashed, thin},
  el/.style={font=\normalsize},
  lbl/.style={font=\small}
]
  % energy axis
  \draw[->] (-0.5,-0.3) -- (-0.5,5) node[above] {$E$};

  % atomic orbitals of the two oxygen atoms
  \foreach \x/\lab in {0/O, 6/O} {
    \draw[level] (\x,1) -- ++(0.8,0) node[midway, el] {$\uparrow\downarrow$};
    \node[lbl, below] at (\x+0.4,0.9) {$2s$};
    \draw[level] (\x-0.5,3.5) -- ++(0.8,0) node[midway, el] {$\uparrow\downarrow$};
    \draw[level] (\x+0.4,3.5) -- ++(0.8,0) node[midway, el] {$\uparrow$};
    \draw[level] (\x+1.3,3.5) -- ++(0.8,0) node[midway, el] {$\uparrow$};
    \node[lbl, below] at (\x+0.8,3.4) {$2p$};
    \node[above] at (\x+0.4,5) {\ce{\lab}};
  }

  % molecular orbitals
  \draw[level] (3,0.3) -- ++(0.8,0) node[midway, el] {$\uparrow\downarrow$};
  \node[lbl, right] at (3.9,0.3) {$\sigma_{2s}$};
  \draw[level] (3,1.7) -- ++(0.8,0) node[midway, el] {$\uparrow\downarrow$};
  \node[lbl, right] at (3.9,1.7) {$\sigma^*_{2s}$};
  \draw[level] (3,2.6) -- ++(0.8,0) node[midway, el] {$\uparrow\downarrow$};
  \node[lbl, right] at (3.9,2.6) {$\sigma_{2p}$};
  \draw[level] (2.5,3.1) -- ++(0.8,0) node[midway, el] {$\uparrow\downarrow$};
  \draw[level] (3.5,3.1) -- ++(0.8,0) node[midway, el] {$\uparrow\downarrow$};
  \node[lbl, right] at (4.4,3.1) {$\pi_{2p}$};
  \draw[level] (2.5,4.1) -- ++(0.8,0) node[midway, el] {$\uparrow$};
  \draw[level] (3.5,4.1) -- ++(0.8,0) node[midway, el] {$\uparrow$};
  \node[lbl, right] at (4.4,4.1) {$\pi^*_{2p}$};
  \draw[level] (3,4.8) -- ++(0.8,0);
  \node[lbl, right] at (3.9,4.8) {$\sigma^*_{2p}$};
  \node[above] at (3.4,5) {\ce{O2}};

  % correlation lines
  \draw[corr] (0.8,1) -- (3,0.3);    \draw[corr] (6,1) -- (3.8,0.3);
  \draw[corr] (0.8,1) -- (3,1.7);    \draw[corr] (6,1) -- (3.8,1.7);
  \draw[corr] (2.1,3.5) -- (3,2.6);  \draw[corr] (5.5,3.5) -- (3.8,2.6);
  \draw[corr] (2.1,3.5) -- (3,4.8);  \draw[corr] (5.5,3.5) -- (3.8,4.8);
\end{tikzpicture}
\end{document}

Do not name a style dash: TikZ already has a key of that name and stops with The key '/tikz/dash' requires a value. To extend the drawing, add levels and arrows in the same pattern; for a ligand field splitting (t2g/eg) the same lines-and-arrows approach works with five d levels on one side. If you would rather not place coordinates by hand, the TikZ generator produces a starting picture you can edit.

Lewis Structures with chemfig and Formulas with mhchem

An MO diagram is often shown next to the Lewis structure it improves on. chemfig draws the structure, with \charge adding lone pairs and single electrons around an atom as a list of angle=symbol pairs: \: is a lone pair, \. a single electron and \| a pair drawn as a line, with 0 = right, 90 = top, 180 = left and 270 = bottom. (Older tutorials use \lewis{2:6:,O}; chemfig 1.6 and later no longer define it, so on a current TeX Live it fails with Undefined control sequence.) mhchem's \ce formats formulas and charges, and works inside modiagram and TikZ labels:

\usepackage{chemfig}
\usepackage[version=4]{mhchem}
\usepackage{modiagram}

\ce{O2}, \ce{N2}, \ce{O2^-}, \ce{O2^2-}, \ce{He2^+}, \ce{2 H2 + O2 -> 2 H2O}

\chemfig{H-H}                                             % H2
\chemfig{\charge{90=\:,270=\:}{O}=\charge{90=\:,270=\:}{O}}   % O=O, two lone pairs each
\chemfig{\charge{180=\:}{N}~\charge{0=\:}{N}}                % N≡N (~ is a triple bond)
\chemfig{\charge{180=\:}{C}~\charge{0=\:}{O}}                % C≡O
\chemfig{\charge{45=\.}{O}}                                  % a single (radical) electron

\begin{figure}[h]
  \centering
  \begin{minipage}{0.3\textwidth}\centering
    \chemfig{\charge{90=\:,270=\:}{O}=\charge{90=\:,270=\:}{O}}
  \end{minipage}
  \begin{minipage}{0.6\textwidth}\centering
    \begin{modiagram}[labels, distance=2.5cm]
      \atom{left}{2p = {0;pair,up,up}}
      \atom{right}{2p = {0;pair,up,up}}
      \molecule{2pMO = {1,0.5;pair,pair,pair,up,up}}
    \end{modiagram}
  \end{minipage}
  \caption{Lewis structure and 2p molecular orbitals of \ce{O2}; bond order $(8-4)/2 = 2$.}
\end{figure}

Names in \molecule[...] and \atom[...] accept \ce too, so \molecule[\ce{O2}]{...} gives a properly formatted subscript.

Exporting the Figure

For a standalone image, put the diagram in a document with \documentclass{standalone} (as in the TikZ example) and compile; the PDF is cropped to the picture and can be dropped into another document with \includegraphics or converted to SVG for a web page with pdftocairo -svg or dvisvgm --pdf. In a long thesis, the external TikZ library (\usetikzlibrary{external}, \tikzexternalize) caches each picture as a PDF so it is not redrawn on every compile; it needs shell escape.

Common Errors and Fixes

Symptom or messageCauseFix
Package modiagram Error: You need to specify the left and right atom first\molecule before both \atom commandsPut \atom{left} and \atom{right} before \molecule
You need to specify both 2p AOs first before you can use 2pMOAn MO is requested whose parent AOs were not given on both sidesAdd the matching 2p= (or 1s=, 2s=) to both atoms
The key 'modiagram/color/blue' is unknowncolor=blue is not how the key worksName the orbital: color={2piy*=blue}
Levels and labels overlapSplittings too large or too small relative to the AO energiesAdjust the energies; give σ and π different splittings; use labels-fs=\scriptsize
Package modiagram Warning: ... MOdiagram ... deprecatedOld environment nameUse \begin{modiagram} and \setmodiagram
Undefined control sequence \ce / \chemfigmhchem or chemfig not loaded\usepackage[version=4]{mhchem}, \usepackage{chemfig}
Undefined control sequence \lewis although chemfig is loaded\lewis is gone from chemfig 1.6 and later; older tutorials still show itUse \charge{90=\:,270=\:}{O}
The key '/tikz/dash' requires a valueA custom style named dash clashes with a TikZ keyRename the style (corr, link)
Electrons in the wrong orbitalsElectron slots given in the wrong orderOrder is σ, πy, πz, π*y, π*z, σ* for 2pMO and σ, σ* for 1sMO/2sMO

Quick Reference

TaskLaTeX
Load the package\usepackage{modiagram}
Atomic orbitals\atom[O]{left}{2s = {0;pair}, 2p = {4;pair,up,up}}
s-type MOs\molecule{1sMO = {0.75;pair,pair}} (σ then σ*)
p-type MOs2pMO = {σ-split,π-split; σ,πy,πz,πy*,πz*,σ*}
Separate bonding / antibonding splittings2pMO = {0.6/2.2, 1.4/1.6; ...}
Energy axis\EnergyAxis, \EnergyAxis[title]
Names and labels\begin{modiagram}[names, labels]
Electron arrows in TikZ\node at (x,y) {$\uparrow\downarrow$};
Chemical formula\ce{O2^-} (mhchem)
Lewis structure\chemfig{\charge{90=\:,270=\:}{O}=\charge{90=\:,270=\:}{O}}
Bond order(bonding − antibonding) / 2

Frequently Asked Questions

How do you calculate bond order from a molecular orbital diagram?

Count the electrons in bonding orbitals, subtract the electrons in antibonding orbitals and divide by two: bond order = (bonding − antibonding) / 2. For O2 that is (8 − 4) / 2 = 2, a double bond; for N2 it is (8 − 2) / 2 = 3; for He2 it is (2 − 2) / 2 = 0, which is why He2 does not exist. A higher bond order means a shorter, stronger bond.

Why is O2 paramagnetic according to MO theory?

O2 has 12 valence electrons. After filling σ2s, σ*2s, σ2p and the two π2p orbitals, two electrons remain for the two degenerate π*2p orbitals. By Hund's rule they occupy one each with parallel spins, so O2 has two unpaired electrons and is attracted into a magnetic field. A Lewis structure, with all electrons paired, cannot explain this; the MO diagram does.

Why is the MO order different for N2 and O2?

For B2, C2 and N2 the 2s and 2p atomic orbitals are close enough in energy that the σ2s and σ2p molecular orbitals mix (s–p mixing). The mixing pushes σ2p up above the π2p pair, so the order is σ2s < σ*2s < π2p < σ2p. In O2 and F2 the 2s–2p gap is larger, the mixing is weak, and σ2p lies below π2p. The two orderings give the same bond order for O2 and N2 but change which orbital is the HOMO.

What LaTeX package draws MO diagrams?

modiagram is the dedicated package: \usepackage{modiagram} gives you a modiagram environment with \atom for the atomic orbitals, \molecule for the molecular orbitals and \EnergyAxis, and it draws the levels, electrons and correlation lines for 1s, 2s and 2p for you. It is built on TikZ, so for anything it does not cover (d orbitals, ligand field diagrams, more than two fragments) you draw the diagram directly in TikZ.

How do I write O2, N2 or O2− with proper formatting in LaTeX?

Load mhchem with \usepackage[version=4]{mhchem} and write \ce{O2}, \ce{N2}, \ce{O2^-} and \ce{CO}. \ce sets the subscripts and charges upright and in the right position, works in text and in math mode, and also handles reaction arrows such as \ce{2 H2 + O2 -> 2 H2O}. It can be used inside modiagram and TikZ labels too.

Next Steps

Diagram drawn? These guides cover the surrounding figure work:

Free LaTeX Tools

Draw chemistry figures faster with AI

Describe the molecule and Octree's AI editor writes the modiagram or TikZ code, fixes the package errors, and compiles the figure in seconds.

Try Octree Free →