pythonmatplotlibrdkit

Get x,y data from RDKit mol instance and plot in matplotlib?


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

Solution

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