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.
importpy2Dmol# 1. Create a viewer objectviewer=py2Dmol.view(size=(600, 600))
# 2. Add pdbviewer.add_pdb('my_protein.pdb', chains=['A', 'B'])
# 3. Show the final, static viewerviewer.show()You can add multiple PDB files as separate, switchable trajectories.
importpy2Dmolviewer=py2Dmol.view()
# Load first trajectoryviewer.add_pdb('simulation1.pdb')
# Start a new trajectoryviewer.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.
importpy2Dmolviewer=py2Dmol.view(
size=(300, 300), # canvas size (width, height)color='auto', # color mode: ["auto","rainbow","chain","plddt"]pastel=0.25, # lighten the colorscolorblind=False, # use colorbind friendly colorsshadow=True, # show shadowoutline=True, # show outlinewidth=3.0, # line widthrotate=False, # auto-rotationautoplay=False, # auto-play (if trajectory or multiple models)box=True, # show box around moleculecontrols=True, # show controlspae=False, # show paepae_size=(300,300), # set pae canvas size (width, height)
)
viewer.add_pdb("my_complex.cif")
viewer.show()importpy2Dmolpy2Dmol.view(autoplay=True).from_pdb('1YNE')importpy2Dmolpy2Dmol.view(rotate=True).from_pdb('1BJP', use_biounit=True, ignore_ligands=True)importpy2Dmolpy2Dmol.view().from_pdb('9D2J')importpy2Dmolpy2Dmol.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.
importnumpyasnpimporttime# Define the wiggle functiondefcircle_morph(n=20, wave=0):
"""n points, constant ~3.8Å bonds, wavy deformation."""bond=3.8perimeter=n*bondradius=perimeter/ (2*np.pi)
angles=np.linspace(0, 2*np.pi, n, endpoint=False)
r=radius* (1+wave*0.2*np.sin(4*angles))
returnnp.column_stack([
r*np.cos(angles),
r*np.sin(angles),
wave*3*np.cos(angles)
])
# 1. Create the viewer objectviewer=py2Dmol.view()
# 2. Show the viewer *before* adding data to enter "Live Mode"viewer.show()
# 3. Now, add frames in a loopforframeinrange(60):
w=np.sin(frame*np.pi/15)
coords=circle_morph(20, w)
plddts=np.full((20,), 80.0)
chains= ['A'] *20atom_types= ['P'] *20# Send the new frame to the live viewerviewer.add(coords, plddts, chains, atom_types)
# Wait a bittime.sleep(0.1)You can manually add coordinates for different molecule types (P, D, R, L).
importnumpyasnpdefhelix(n, radius=2.3, rise=1.5, rotation=100):
"""Generate helical coordinates."""angles=np.radians(rotation) *np.arange(n)
returnnp.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']*6types= ['P']*50+ ['D']*30+ ['L']*6viewer=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.