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#

https://mybinder.org/badge_logo.svg

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#

https://mybinder.org/badge_logo.svg

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)>

Note

The interactive part is not shown in the output above. They can be found in the binder notebook:

https://mybinder.org/badge_logo.svg