0

I'm trying to plot a molecule from a SMILES in RDKit and I have found out you can get a PIL Image by using rdkit.Chem.Draw.MolToImage(). My problem with that is that this only returns a raster type image (as far as I can tell) which isn't scale-able like an svg. I can't find a way to extract the node data from a mol instance in the docs so that I can build my own visualiser for molecules in matplotlib nor can I find a function that can return a vector image type in the RDKit docs. Can anyone tell me how I can do either of the two? I really need a vector image type for what I want to do, not a raster image type and I want to plot it in matplotlib after I get the necessary data.

This is my code:

import matplotlib.pyplot as plt
from rdkit import Chem
from rdkit.Chem import Draw
import numpy as np



def plot():

    nrows, ncols = (1,3)

    fig = plt.figure(frameon=False,constrained_layout=True)
    gs = fig.add_gridspec(nrows=nrows, ncols=ncols, hspace=0, wspace=0)

    for i in range(nrows):
        for j in range(ncols):
            ax = plt.subplot(gs[i,j])
            ax.set_box_aspect(1)
            ax.axis('off')

    smiles = 'O[C@]1([C@H](CCCC1)CN(C)C)C2=CC(OC)=CC=C2'
    ID = 'ANCDHA'
    
    mol = Chem.MolFromSmiles(smiles)
    mol_img = Chem.Draw.MolToImage(mol,size=(600,600))
    mol_img = np.asarray(mol_img)


    fig.axes[0].text(1.,0.5,ID,size=15,ha='right',va='center')
    fig.axes[1].imshow(mol_img)

    plt.show()

plot()
J.Doe
  • 224
  • 1
  • 4
  • 19

2 Answers2

1

Here is how you can display and get an SVG file of a molecule.

from rdkit import Chem
from rdkit.Chem.Draw import rdMolDraw2D
from IPython.display import SVG
from cairosvg import svg2png

input_smiles= 'O[C@]1([C@H](CCCC1)CN(C)C)C2=CC(OC)=CC=C2'
mol = Chem.MolFromSmiles(input_smiles)
mol = rdMolDraw2D.PrepareMolForDrawing(mol, kekulize=True)
smiles_mol_prepared = Chem.MolToSmiles(mol)
drawer = rdMolDraw2D.MolDraw2DSVG(400, 400)
opts = drawer.drawOptions()
drawer.DrawMolecule(mol)
drawer.FinishDrawing()
svg = drawer.GetDrawingText()
display(SVG(svg.replace('svg:','')))

# Using cairosvg
svg2png(bytestring=svg, write_to="smiles.png")

This outputs a smiles.png that looks like below:
enter image description here

Vandan Revanur
  • 459
  • 6
  • 17
1

Just a little variation from Vandan's answer to get the SVG into a file:

from rdkit import Chem
from rdkit.Chem.Draw import rdMolDraw2D
from IPython.display import SVG


def smiles_to_svg(input_smiles: str, svg_file_name:str,  size=(400, 200)):

    molecule= Chem.MolFromSmiles(input_smiles)
    drawer = rdMolDraw2D.MolDraw2DSVG(size[0], size[1])
    drawer.DrawMolecule(molecule) 
    drawer.FinishDrawing()
    svg = drawer.GetDrawingText().replace('svg:','')
    with open(svg_file_name, 'w') as f:
        f.write(svg)
    return 
smiles_to_svg(input_smiles= 'O[C@]1([C@H](CCCC1)CN(C)C)C2=CC(OC)=CC=C2', svg_file_name= 'test_svg.svg')
shobarium
  • 26
  • 1