A Python library for visualizing protein, DNA, and RNA structures in 2D, designed for use in Google Colab and Jupyter environments.
Bonus: online interactive version
pip install py2DmolThis will load the PDB, including all its models as frames, and display it.
import py2Dmol
# 1. Create a viewer object
viewer = py2Dmol.view(size=(600, 600))
# 2. Add pdb
viewer.add_pdb('my_protein.pdb', chains=['A', 'B'])
# 3. Show the final, static viewer
viewer.show()You can add multiple PDB files as separate, switchable trajectories.
import py2Dmol
viewer = py2Dmol.view()
# Load first trajectory
viewer.add_pdb('simulation1.pdb')
# Start a new trajectory
viewer.add_pdb('simulation2.pdb', new_obj=True)
# Use the dropdown to switch between "0" and "1"
viewer.show()You can pass several options to the view constructor.
import py2Dmol
viewer = py2Dmol.view(
size=(300, 300), # canvas size (width, height)
color='auto', # color mode: ["auto","rainbow","chain","plddt"]
pastel=0.25, # lighten the colors
colorblind=False, # use colorbind friendly colors
shadow=True, # show shadow
outline=True, # show outline
width=3.0, # line width
rotate=False, # auto-rotation
autoplay=False, # auto-play (if trajectory or multiple models)
box=True, # show box around molecule
controls=True, # show controls
pae=False, # show pae
pae_size=(300,300), # set pae canvas size (width, height)
)
viewer.add_pdb("my_complex.cif")
viewer.show()import py2Dmol
py2Dmol.view(autoplay=True).from_pdb('1YNE')import py2Dmol
py2Dmol.view(rotate=True).from_pdb('1BJP', use_biounit=True, ignore_ligands=True)import py2Dmol
py2Dmol.view().from_pdb('9D2J')import py2Dmol
py2Dmol.view(pae=True).from_afdb('Q5VSL9')py2Dmol has two modes, determined by when you call viewer.show().
You call add() or add_pdb() first to load all your data, and then call show() at the end.
- Workflow:
viewer.add*()➔viewer.show() - Result: Creates a single, 100% persistent viewer that contains all your data.
This mode is for live, dynamic updates (e.g., in a loop). You call show() before you add any data.
- Workflow:
viewer.show()➔viewer.add*() - Result:
show()creates an empty, live viewer. Subsequentadd()calls send data to it one by one.
This example only works when run in a notebook. It will dynamically add frames to the viewer one at a time.
import numpy as np
import time
# Define the wiggle function
def circle_morph(n=20, wave=0):
"""n points, constant ~3.8Å bonds, wavy deformation."""
bond = 3.8
perimeter = n * bond
radius = perimeter / (2 * np.pi)
angles = np.linspace(0, 2*np.pi, n, endpoint=False)
r = radius * (1 + wave * 0.2 * np.sin(4 * angles))
return np.column_stack([
r * np.cos(angles),
r * np.sin(angles),
wave * 3 * np.cos(angles)
])
# 1. Create the viewer object
viewer = py2Dmol.view()
# 2. Show the viewer *before* adding data to enter "Live Mode"
viewer.show()
# 3. Now, add frames in a loop
for frame in range(60):
w = np.sin(frame * np.pi / 15)
coords = circle_morph(20, w)
plddts = np.full((20,), 80.0)
chains = ['A'] * 20
atom_types = ['P'] * 20
# Send the new frame to the live viewer
viewer.add(coords, plddts, chains, atom_types)
# Wait a bit
time.sleep(0.1)You can manually add coordinates for different molecule types (P, D, R, L).
import numpy as np
def helix(n, radius=2.3, rise=1.5, rotation=100):
"""Generate helical coordinates."""
angles = np.radians(rotation) * np.arange(n)
return np.column_stack([
radius * np.cos(angles),
radius * np.sin(angles),
rise * np.arange(n)
])
# Protein helix (50 residues)
protein = helix(50)
protein[:, 0] += 15 # offset x
# DNA strand (30 bases)
dna = helix(30, radius=10, rise=3.4, rotation=36)
dna[:, 0] -= 15 # offset x
# Ligand ring (6 atoms)
angles = np.linspace(0, 2*np.pi, 6, endpoint=False)
ligand = np.column_stack([
1.4 * np.cos(angles),
1.4 * np.sin(angles),
np.full(6, 40)
])
# Combine everything (86 atoms total)
coords = np.vstack([protein, dna, ligand])
plddts = np.concatenate([np.full(50, 90), np.full(30, 85), np.full(6, 70)])
chains = ['A']*50 + ['B']*30 + ['L']*6
types = ['P']*50 + ['D']*30 + ['L']*6
viewer = py2Dmol.view((400,300),rotate=True)
viewer.add(coords, plddts, chains, types)
viewer.show()| Molecule Type | Atom Type Code | Representative Atom | Purpose |
|---|---|---|---|
| Protein | P | CA (C-alpha) | Backbone trace |
| DNA | D | C4' (sugar carbon) | Backbone trace |
| RNA | R | C4' (sugar carbon) | Backbone trace |
| Ligand | L | All heavy atoms | Full structure |
The viewer uses different distance thresholds for creating bonds:
- Protein (CA-CA): 5.0 Å
- DNA/RNA (C4'-C4'): 7.5 Å
- Ligand bonds: 2.0 Å
The viewer supports multiple coloring schemes:
- auto (default): Automatically chooses 'chain' if multiple chains are present, otherwise 'rainbow'.
- rainbow: Colors atoms sequentially from N-terminus to C-terminus (or 5' to 3' for nucleic acids)
- plddt: Colors based on B-factor/pLDDT scores (useful for AlphaFold predictions)
- chain: Each chain receives a distinct color
- PDB (.pdb)
- mmCIF (.cif)
Both formats support multi-model files, which are loaded as frames in a single trajectory.