py3Dmol in Jupyter

Sometimes you want to see the 3D structure of molecule you are manipulating in jupyter, but you have to save it as a file with coordinates and open it in PyMol. This is very inconvenient. Although you can use PyMol to render image and show it in jupyter, but it is only a static image. Here I recommand a python package py3Dmol, which is a simple jupyter widget based on a JavaScript library 3Dmol.js. JavaScript can run in almost any browser, so you can use it in jupyter notebooks and in web pages.

Installation

Installation is easy:

1
pip install py3Dmol

Show a molecule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import py3Dmol

def MolTo3DView(mol, size=(300, 300), style="stick", surface=False, opacity=0.5):
"""Draw molecule in 3D

Args:
----
mol: rdMol, molecule to show
size: tuple(int, int), canvas size
style: str, type of drawing molecule
style can be 'line', 'stick', 'sphere', 'carton'
surface, bool, display SAS
opacity, float, opacity of surface, range 0.0-1.0
Return:
----
viewer: py3Dmol.view, a class for constructing embedded 3Dmol.js views in ipython notebooks.
"""
assert style in ('line', 'stick', 'sphere', 'carton')
mblock = Chem.MolToMolBlock(mol)
viewer = py3Dmol.view(width=size[0], height=size[1])
viewer.addModel(mblock, 'mol')
viewer.setStyle({style:{}})
if surface:
viewer.addSurface(py3Dmol.SAS, {'opacity': opacity})
viewer.zoomTo()
return viewer

Show an interactive window by viewer.show method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from rdkit import Chem
from rdkit.Chem import AllChem

def smi2conf(smiles):
'''Convert SMILES to rdkit.Mol with 3D coordinates'''
mol = Chem.MolFromSmiles(smiles)
if mol is not None:
mol = Chem.AddHs(mol)
AllChem.EmbedMolecule(mol)
AllChem.MMFFOptimizeMolecule(mol, maxIters=200)
return mol
else:
return None

smi = 'COc3nc(OCc2ccc(C#N)c(c1ccc(C(=O)O)cc1)c2P(=O)(O)O)ccc3C[NH2+]CC(I)NC(=O)C(F)(Cl)Br'
conf = smi2conf(smi)
viewer = MolTo3DView(conf, size=(600, 300), style='sphere')
viewer.show()

py3Dmol

Also, use viewer.png method to render a PNG picture.

1
2
viewer = MolTo3DView(conf, size=(600, 300), style='sphere')
viewer.show()

More detail usage can be found on 3Dmol.js offical documents, returned viewer has exact same api as 3Dmol.GLViewer

More Examples

With ipywidgets.IntSlider

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from ipywidgets import interact,fixed,IntSlider
import ipywidgets

smis = [ 'COc3nc(OCc2ccc(C#N)c(c1ccc(C(=O)O)cc1)c2P(=O)(O)O)ccc3C[NH2+]CC(I)NC(=O)C(F)(Cl)Br',
'CC(NCCNCC1=CC=C(OCC2=C(C)C(C3=CC=CC=C3)=CC=C2)N=C1OC)=O',
'Cc1c(COc2cc(OCc3cccc(c3)C#N)c(CN3C[C@H](O)C[C@H]3C(O)=O)cc2Cl)cccc1-c1ccc2OCCOc2c1',
'CCCCC(=O)NCCCCC(=O)NCCCCCC(=O)[O-]',
"CC(NCCNCC1=CC=C(OCC2=C(C)C(C3=CC=CC=C3)=CC=C2)N=C1OC)=O"]

confs = [smi2conf(s) for s in smis]

def conf_viewer(idx):
mol = confs[idx]
return MolTo3DView(mol).show()

interact(conf_viewer, idx=ipywidgets.IntSlider(min=0,max=len(class_0_list)-1, step=1))

py3Dmol

Style Selector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from ipywidgets import interact,fixed,IntSlider
import ipywidgets

smis = [ 'COc3nc(OCc2ccc(C#N)c(c1ccc(C(=O)O)cc1)c2P(=O)(O)O)ccc3C[NH2+]CC(I)NC(=O)C(F)(Cl)Br',
'CC(NCCNCC1=CC=C(OCC2=C(C)C(C3=CC=CC=C3)=CC=C2)N=C1OC)=O',
'Cc1c(COc2cc(OCc3cccc(c3)C#N)c(CN3C[C@H](O)C[C@H]3C(O)=O)cc2Cl)cccc1-c1ccc2OCCOc2c1',
'CCCCC(=O)NCCCCC(=O)NCCCCCC(=O)[O-]',
"CC(NCCNCC1=CC=C(OCC2=C(C)C(C3=CC=CC=C3)=CC=C2)N=C1OC)=O"]

confs = [smi2conf(s) for s in smis]

def style_selector(idx, s):
conf = confs[idx]
return MolTo3DView(conf, style=s).show()

interact(style_selector,
idx=ipywidgets.IntSlider(min=0,max=len(class_0_list)-1, step=1),
s=ipywidgets.Dropdown(
options=['line', 'stick', 'sphere'],
value='line',
description='Style:'))

py3Dmol

Display molecule encoded by SMILES

1
2
3
4
5
6
7
@interact
def smi2viewer(smi='CC=O'):
try:
conf = smi2conf(smi)
return MolTo3DView(conf).show()
except:
return None

py3Dmol