Visualizing molecules with RDKit and py3Dmol#
↺ Newest | Next → July 18, 2022 () by Anders Lervik | Category: chemistry Tagged: chemistry | jupyter | molecules | py3dmol | python | rdkit
Introduction#
py3Dmol is a very useful widget for molecular visualization in jupyter. You can add visualizations like this one:
directly in your jupyter notebooks with very little code. I find it especially useful together with RDKit for working with molecules and displaying them.
A short example - Caffeine#
This is a short example of using RDKit together with py3Dmol for visualizing molecules.
First, import RDKit and py3Dmol. I use rdkit.Chem.rdCoordGen since I like the structures RDKit draws based on this.
[1]:
from rdkit import Chem
from rdkit.Chem import (
AllChem,
rdCoordGen,
)
from rdkit.Chem.Draw import IPythonConsole
IPythonConsole.ipython_useSVG=True # Use higher quality images for molecules
import py3Dmol
Create caffeine from smiles and draw the molecule with RDKit:
[2]:
caffeine = Chem.MolFromSmiles("CN1C=NC2=C1C(=O)N(C(=O)N2C)C")
rdCoordGen.AddCoords(caffeine)
caffeine
[2]:
Use RDKit to generate 3D-coordinates for caffeine:
[3]:
def molecule_to_3d(molecule):
mol = Chem.Mol(molecule)
mol = AllChem.AddHs(mol, addCoords=True)
AllChem.EmbedMolecule(mol)
AllChem.MMFFOptimizeMolecule(mol)
return mol
caffeine_3d = molecule_to_3d(caffeine)
Display the molecule with py3Dmol, using stick and sphere:
[4]:
view = py3Dmol.view(
data=Chem.MolToMolBlock(caffeine_3d), # Convert the RDKit molecule for py3Dmol
style={"stick": {}, "sphere": {"scale": 0.3}}
)
view.zoomTo()
You appear to be running in JupyterLab (or JavaScript failed to load for some other reason). You need to install the 3dmol extension:
jupyter labextension install jupyterlab_3dmol
[4]:
<py3Dmol.view at 0x7fb5005ea2b0>
Note
The RDKit molecule is converted to a mol block with Chem.MolToMolBlock before passing it to py3Dmol. This method is also very useful for generating initial configurations for other programs, for instance, pyscf.
A longer example - explore molecules#
In this notebook, I use ipywidgets to create an interactive molecule explorer. This can, for instance, be useful if we have a data set containing a lot of molecules and we want to visualize the molecules.
[1]:
import pandas as pd
from io import StringIO
from rdkit import Chem
from rdkit.Chem import (
AllChem,
rdCoordGen,
)
from rdkit.Chem.Draw import IPythonConsole
IPythonConsole.ipython_useSVG = True # Use higher quality images for molecules
import py3Dmol
from ipywidgets import interact, Dropdown
[2]:
data_set = StringIO(
"""names,smiles
Amigdalin,N#CC(OC1OC(COC2OC(CO)C(O)C(O)C2O)C(O)C(O)C1O)c1ccccc1
Fenfuram,Cc1occc1C(=O)Nc1ccccc1
citral,CC(C)=CCCC(C)=CC=O
Picene,c1ccc2c(c1)ccc1c2ccc2c3ccccc3ccc21
Thiophene,c1ccsc1
benzothiazole,c1ccc2scnc2c1
"2,2,4,6,6'-PCB",Clc1cc(Cl)c(-c2c(Cl)cccc2Cl)c(Cl)c1
Estradiol,CC12CCC3c4ccc(O)cc4CCC3C1CCC2O
Dieldrin,ClC1=C(Cl)C2(Cl)C3C4CC(C5OC45)C3C1(Cl)C2(Cl)Cl
Rotenone,C=C(C)C1Cc2c(ccc3c2OC2COc4cc(OC)c(OC)cc4C2C3=O)O1
2-pyrrolidone,O=C1CCCN1
2-Chloronapthalene,Clc1ccc2ccccc2c1
1-Pentene ,C=CCCC
Primidone,CCC1(c2ccccc2)C(=O)NCNC1=O
Tetradecane,CCCCCCCCCCCCCC
2-Chloropropane,CC(C)Cl
2-Methylbutanol,CCC(C)CO
Benzonitrile,N#Cc1ccccc1
Diazinon,CCOP(=S)(OCC)Oc1cc(C)nc(C(C)C)n1
2-Undecanol,CCCCCCCCCC(C)O"""
)
[3]:
table = pd.read_csv(data_set)
table
[3]:
names | smiles | |
---|---|---|
0 | Amigdalin | N#CC(OC1OC(COC2OC(CO)C(O)C(O)C2O)C(O)C(O)C1O)c... |
1 | Fenfuram | Cc1occc1C(=O)Nc1ccccc1 |
2 | citral | CC(C)=CCCC(C)=CC=O |
3 | Picene | c1ccc2c(c1)ccc1c2ccc2c3ccccc3ccc21 |
4 | Thiophene | c1ccsc1 |
5 | benzothiazole | c1ccc2scnc2c1 |
6 | 2,2,4,6,6'-PCB | Clc1cc(Cl)c(-c2c(Cl)cccc2Cl)c(Cl)c1 |
7 | Estradiol | CC12CCC3c4ccc(O)cc4CCC3C1CCC2O |
8 | Dieldrin | ClC1=C(Cl)C2(Cl)C3C4CC(C5OC45)C3C1(Cl)C2(Cl)Cl |
9 | Rotenone | C=C(C)C1Cc2c(ccc3c2OC2COc4cc(OC)c(OC)cc4C2C3=O)O1 |
10 | 2-pyrrolidone | O=C1CCCN1 |
11 | 2-Chloronapthalene | Clc1ccc2ccccc2c1 |
12 | 1-Pentene | C=CCCC |
13 | Primidone | CCC1(c2ccccc2)C(=O)NCNC1=O |
14 | Tetradecane | CCCCCCCCCCCCCC |
15 | 2-Chloropropane | CC(C)Cl |
16 | 2-Methylbutanol | CCC(C)CO |
17 | Benzonitrile | N#Cc1ccccc1 |
18 | Diazinon | CCOP(=S)(OCC)Oc1cc(C)nc(C(C)C)n1 |
19 | 2-Undecanol | CCCCCCCCCC(C)O |
[4]:
def molecule_to_3d(molecule):
"""Add 3D coordinates for RDKit molecules."""
mol = Chem.Mol(molecule)
mol = AllChem.AddHs(mol, addCoords=True)
AllChem.EmbedMolecule(mol)
AllChem.MMFFOptimizeMolecule(mol)
return mol
def molecules_from_smiles(smiles):
"""Generate RDKit molecules from smiles."""
molecules = []
for smilei in smiles:
mol = Chem.MolFromSmiles(smilei)
rdCoordGen.AddCoords(mol)
molecules.append(mol)
return molecules
[5]:
names = table["names"].values
smiles = table["smiles"].values
molecules = molecules_from_smiles(smiles)
molecules_3d = [molecule_to_3d(i) for i in molecules]
Create a Dropdown selector for the 2D structure of the molecules:
[6]:
def view_2d(molecule):
return molecule
molecules_options = [(i, j) for i, j in zip(names, molecules)]
dropdown = Dropdown(
options=molecules_options, value=molecules[0], description="Molecule:"
)
interact(
view_2d,
molecule=dropdown,
)
[6]:
<function __main__.view_2d(molecule)>
Create a Dropdown selector for the 3D structure of the molecules:
[7]:
def view_3d(molecule):
view = py3Dmol.view(
data=Chem.MolToMolBlock(molecule), # Convert the RDKit molecule for py3Dmol
style={"stick": {}, "sphere": {"scale": 0.3}}
)
view.zoomTo()
return view
molecules_options = [(i, j) for i, j in zip(names, molecules_3d)]
dropdown = Dropdown(
options=molecules_options, value=molecules_3d[0], description="Molecule:"
)
interact(
view_3d,
molecule=dropdown,
)
[7]:
<function __main__.view_3d(molecule)>