Interactive Molecular Visualization

py3Dmol

Display structures, conformers, labels, and cube isosurfaces interactively in Jupyter notebooks and Google Colab.

Role
Notebook and web molecular viewer
Typical input
XYZ, SDF/MOL, PDB, cube
Typical output
Interactive WebGL visualization

1. Setup

py3Dmol wraps 3Dmol.js in a notebook-friendly Python API. The rendered viewer is browser-side WebGL; save the source structure and viewing parameters alongside screenshots.

Python
import py3Dmol

view = py3Dmol.view(width=640, height=480)
view.addModel(xyz_text, "xyz")
view.setStyle({"stick": {}, "sphere": {"scale": 0.25}})
view.zoomTo()
view.show()

Install with pip install py3Dmol. In notebooks, call show() only after models, styles, surfaces, and camera settings have been added.

2. XYZ, SDF, and PDB

XYZ supplies coordinates but normally lacks bond orders. SDF/MOL carries connectivity and properties; PDB supports biomolecular records. Choose a format that preserves the information needed for the figure.

with open("structure.sdf", encoding="utf-8") as handle:
    sdf_text = handle.read()
view.addModel(sdf_text, "sdf")
view.setStyle({"stick": {}})
view.zoomTo()

3. RDKit integration

Convert an RDKit conformer to a Mol block and add it with addModel. Explicitly choose the conformer ID and hydrogen treatment.

Python
from rdkit import Chem

molblock = Chem.MolToMolBlock(mol, confId=0)
view.addModel(molblock, "mol")

RDKit coordinates are preserved in the Mol block. If hydrogens were removed for display, document that choice and do not use the displayed atom count as analytical data.

4. Styles and labels

Use stick, line, sphere, and cartoon styles for different tasks. Atom labels, selections, and colors should convey chemical information rather than decoration.

Selections can use element, atom index, residue, chain, or model. Labels and measurements are annotations; verify distances against the underlying coordinates rather than reading them from a screenshot.

view.addLabel("reactive center", {
    "position": {"x": 0.0, "y": 0.0, "z": 0.0},
    "backgroundColor": "white", "fontColor": "black"
})
view.addLine({"start": {"x": 0, "y": 0, "z": 0},
              "end": {"x": 1.5, "y": 0, "z": 0}})

5. Conformer comparison

Use separate viewers or models with controlled alignment to compare conformers. Do not imply that an unweighted set of displayed conformers is a thermodynamic population.

for conf_id in range(mol.GetNumConformers()):
    block = Chem.MolToMolBlock(mol, confId=conf_id)
    view.addModel(block, "mol")
view.setStyle({"stick": {}})

6. Cube isosurfaces

Add volumetric data and render positive and negative surfaces separately for signed orbitals. For electrostatic potential mapping or NCI coloring, keep the shape field and color field conceptually distinct.

view.addVolumetricData(cube_text, "cube", {
    "isoval": 0.03, "color": "blue", "opacity": 0.75
})
view.addVolumetricData(cube_text, "cube", {
    "isoval": -0.03, "color": "red", "opacity": 0.75
})

7. Publishing and reproducibility

For a public page, provide a fallback description or image when WebGL is unavailable, constrain viewer dimensions responsively, and test touch interaction. Store the source structure, cube file, isovalues, colors, selections, and camera orientation so the view can be reproduced.

A viewer is not the primary data record

Screenshots and interactive views are presentation layers. Preserve the numerical coordinates and volumetric files separately.

8. Web-display checks

  1. Confirm a nonblank canvas.
  2. Check framing after zoomTo().
  3. Test mouse rotation and zoom.
  4. Verify colors and isovalues.
  5. Inspect desktop and mobile dimensions.

9. References

Last reviewed: August 4, 2026. Check the linked official documentation for syntax specific to the installed software version.