1
2
3
4
5 import os,re
6 from rdkit.six import iteritems
7 from rdkit.Chem.Draw.MolDrawing import MolDrawing,DrawingOptions
8 from rdkit.Chem.Draw.rdMolDraw2D import *
9
40
55
56 -def MolToImage(mol, size=(300,300), kekulize=True, wedgeBonds=True,
57 fitImage=False, options=None, canvas=None, **kwargs):
58 """Returns a PIL image containing a drawing of the molecule
59
60 ARGUMENTS:
61
62 - kekulize: run kekulization routine on input `mol` (default True)
63
64 - size: final image size, in pixel (default (300,300))
65
66 - wedgeBonds: draw wedge (stereo) bonds (default True)
67
68 - highlightAtoms: list of atoms to highlight (default [])
69
70 - highlightMap: dictionary of (atom, color) pairs (default None)
71
72 - highlightBonds: list of bonds to highlight (default [])
73
74 - highlightColor: RGB color as tuple (default [1, 0, 0])
75
76 NOTE:
77
78 use 'matplotlib.colors.to_rgb()' to convert string and
79 HTML color codes into the RGB tuple representation, eg.
80
81 from matplotlib.colors import ColorConverter
82 img = Draw.MolToImage(m, highlightAtoms=[1,2], highlightColor=ColorConverter().to_rgb('aqua'))
83 img.save("molecule.png")
84
85 RETURNS:
86
87 a PIL Image object
88 """
89
90 if not mol:
91 raise ValueError('Null molecule provided')
92 if canvas is None:
93 img,canvas=_createCanvas(size)
94 else:
95 img=None
96
97 if options is None:
98 options = DrawingOptions()
99 if fitImage:
100 options.dotsPerAngstrom = int(min(size) / 10)
101 options.wedgeDashedBonds = wedgeBonds
102 if 'highlightColor' in kwargs:
103 color = kwargs.pop('highlightColor', (1, 0, 0))
104 options.selectColor = color
105
106 drawer = MolDrawing(canvas=canvas,drawingOptions=options)
107
108 if kekulize:
109 from rdkit import Chem
110 mol = Chem.Mol(mol.ToBinary())
111 Chem.Kekulize(mol)
112
113 if not mol.GetNumConformers():
114 from rdkit.Chem import AllChem
115 AllChem.Compute2DCoords(mol)
116
117 if 'legend' in kwargs:
118 legend = kwargs['legend']
119 del kwargs['legend']
120 else:
121 legend=''
122
123 drawer.AddMol(mol,**kwargs)
124
125 if legend:
126 from rdkit.Chem.Draw.MolDrawing import Font
127 bbox = drawer.boundingBoxes[mol]
128 pos = size[0]/2,int(.94*size[1]),0
129
130
131
132
133 font=Font(face='sans',size=12)
134 canvas.addCanvasText(legend,pos,font)
135
136 if kwargs.get('returnCanvas',False):
137 return img,canvas,drawer
138 else:
139 canvas.flush()
140 return img
141
142 -def MolToFile(mol,fileName,size=(300,300),kekulize=True, wedgeBonds=True,
143 imageType=None, fitImage=False, options=None, **kwargs):
182
183 -def MolToImageFile(mol,filename,size=(300,300),kekulize=True, wedgeBonds=True,
184 **kwargs):
185 """ DEPRECATED: please use MolToFile instead
186
187 """
188 img = MolToImage(mol,size=size,kekulize=kekulize,wedgeBonds=wedgeBonds,**kwargs)
189 img.save(filename)
190
191 tkRoot=None
192 tkLabel=None
193 tkPI=None
194 -def ShowMol(mol,size=(300,300),kekulize=True,wedgeBonds=True,
195 title='RDKit Molecule',**kwargs):
196 """ Generates a picture of a molecule and displays it in a Tkinter window
197 """
198 global tkRoot,tkLabel,tkPI
199 try:
200 import Tkinter
201 except ImportError:
202 import tkinter as Tkinter
203 try:
204 import ImageTk
205 except ImportError:
206 from PIL import ImageTk
207
208 img = MolToImage(mol,size,kekulize,wedgeBonds,**kwargs)
209
210 if not tkRoot:
211 tkRoot = Tkinter.Tk()
212 tkRoot.title(title)
213 tkPI = ImageTk.PhotoImage(img)
214 tkLabel = Tkinter.Label(tkRoot,image=tkPI)
215 tkLabel.place(x=0,y=0,width=img.size[0],height=img.size[1])
216 else:
217 tkPI.paste(img)
218 tkRoot.geometry('%dx%d'%(img.size))
219
220
221 -def MolToMPL(mol,size=(300,300),kekulize=True, wedgeBonds=True,
222 imageType=None, fitImage=False, options=None, **kwargs):
252
254 """
255 useful things to do with these:
256 fig.axes[0].imshow(z,cmap=cm.gray,interpolation='bilinear',origin='lower',extent=(0,1,0,1))
257 fig.axes[0].contour(x,y,z,20,colors='k')
258
259 fig=Draw.MolToMPL(m);
260 contribs=Crippen.rdMolDescriptors._CalcCrippenContribs(m)
261 logps,mrs=zip(*contribs)
262 x,y,z=Draw.calcAtomGaussians(m,0.03,step=0.01,weights=logps)
263 fig.axes[0].imshow(z,cmap=cm.jet,interpolation='bilinear',origin='lower',extent=(0,1,0,1))
264 fig.axes[0].contour(x,y,z,20,colors='k',alpha=0.5)
265 fig.savefig('coumlogps.colored.png',bbox_inches='tight')
266
267
268 """
269 import numpy
270 from matplotlib import mlab
271 x = numpy.arange(0,1,step)
272 y = numpy.arange(0,1,step)
273 X,Y = numpy.meshgrid(x,y)
274 if weights is None:
275 weights=[1.]*mol.GetNumAtoms()
276 Z = mlab.bivariate_normal(X,Y,a,a,mol._atomPs[0][0], mol._atomPs[0][1])*weights[0]
277 for i in range(1,mol.GetNumAtoms()):
278 Zp = mlab.bivariate_normal(X,Y,a,a,mol._atomPs[i][0], mol._atomPs[i][1])
279 Z += Zp*weights[i]
280 return X,Y,Z
281
282
283 -def MolsToImage(mols, subImgSize=(200,200),legends=None,**kwargs):
284 """
285 """
286 try:
287 import Image
288 except ImportError:
289 from PIL import Image
290 if legends is None: legends = [None]*len(mols)
291 res = Image.new("RGBA",(subImgSize[0]*len(mols),subImgSize[1]))
292 for i,mol in enumerate(mols):
293 res.paste(MolToImage(mol,subImgSize,legend=legends[i],**kwargs),(i*subImgSize[0],0))
294 return res
295
296 -def _moltoimg(mol,sz,highlights,legend,**kwargs):
297 try:
298 import Image
299 except ImportError:
300 from PIL import Image
301 from rdkit.Chem.Draw import rdMolDraw2D
302 if not hasattr(rdMolDraw2D,'MolDraw2DCairo'):
303 img = MolToImage(mol,sz,legend=legend,highlightAtoms=highlights,
304 **kwargs)
305 else:
306 nmol = rdMolDraw2D.PrepareMolForDrawing(mol,kekulize=kwargs.get('kekulize',True))
307 d2d = rdMolDraw2D.MolDraw2DCairo(sz[0],sz[1])
308 d2d.DrawMolecule(nmol,legend=legend,highlightAtoms=highlights)
309 from io import BytesIO
310 d2d.FinishDrawing()
311 sio = BytesIO(d2d.GetDrawingText())
312 img = Image.open(sio)
313 return img
314
315 -def _MolsToGridImage(mols,molsPerRow=3,subImgSize=(200,200),legends=None,
316 highlightAtomLists=None,**kwargs):
317 """ returns a PIL Image of the grid
318 """
319 try:
320 import Image
321 except ImportError:
322 from PIL import Image
323 if legends is None: legends = ['']*len(mols)
324
325 nRows = len(mols)//molsPerRow
326 if len(mols)%molsPerRow : nRows+=1
327
328 res = Image.new("RGBA",(molsPerRow*subImgSize[0],nRows*subImgSize[1]),(255,255,255,0))
329 for i,mol in enumerate(mols):
330 row = i//molsPerRow
331 col = i%molsPerRow
332 highlights=None
333 if highlightAtomLists and highlightAtomLists[i]:
334 highlights=highlightAtomLists[i]
335 if mol is not None:
336 img = _moltoimg(mol,subImgSize,highlights,legends[i],**kwargs)
337 res.paste(img,(col*subImgSize[0],row*subImgSize[1]))
338 return res
339
340 -def _MolsToGridSVG(mols,molsPerRow=3,subImgSize=(200,200),legends=None,
341 highlightAtomLists=None,stripSVGNamespace=True,**kwargs):
342 """ returns an SVG of the grid
343 """
344 matcher = re.compile(r'^(<.*>\n)(<svg:rect .*</svg\:rect>\n)(.*)</svg\:svg>',re.DOTALL)
345 if legends is None: legends = ['']*len(mols)
346 hdr=''
347 ftr='</svg:svg>'
348 rect=''
349
350 nRows = len(mols)//molsPerRow
351 if len(mols)%molsPerRow : nRows+=1
352
353 blocks = ['']*(nRows*molsPerRow)
354
355 fullSize=(molsPerRow*subImgSize[0],nRows*subImgSize[1])
356 for i,mol in enumerate(mols):
357 highlights=None
358 if highlightAtomLists and highlightAtomLists[i]:
359 highlights=highlightAtomLists[i]
360 if mol is not None:
361 nmol = rdMolDraw2D.PrepareMolForDrawing(mol,kekulize=kwargs.get('kekulize',True))
362 d2d = rdMolDraw2D.MolDraw2DSVG(subImgSize[0],subImgSize[1])
363 d2d.DrawMolecule(nmol,legend=legends[i],highlightAtoms=highlights)
364 d2d.FinishDrawing()
365 txt = d2d.GetDrawingText()
366 h,r,b = matcher.match(txt).groups()
367 if not hdr:
368 hdr = h.replace("width='%dpx' height='%dpx' >"%subImgSize,"width='%dpx' height='%dpx' >"%fullSize)
369 if not rect:
370 rect = r
371 blocks[i] = b
372 for i,elem in enumerate(blocks):
373 row = i//molsPerRow
374 col = i%molsPerRow
375 elem = rect+elem
376 blocks[i] = '<g transform="translate(%d,%d)" >%s</g>'%(col*subImgSize[0],row*subImgSize[1],elem)
377 res = hdr + '\n'.join(blocks)+ftr
378 if stripSVGNamespace:
379 res = res.replace('svg:','')
380 return res
381
382 -def MolsToGridImage(mols,molsPerRow=3,subImgSize=(200,200),legends=None,
383 highlightAtomLists=None,useSVG=False,**kwargs):
384 if useSVG:
385 return _MolsToGridSVG(mols,molsPerRow=molsPerRow,subImgSize=subImgSize,
386 legends=legends, highlightAtomLists=highlightAtomLists, **kwargs)
387 else:
388 return _MolsToGridImage(mols,molsPerRow=molsPerRow,subImgSize=subImgSize,
389 legends=legends, highlightAtomLists=highlightAtomLists, **kwargs)
390
392 """
393 """
394 try:
395 import Image
396 except ImportError:
397 from PIL import Image
398
399 mols = []
400 for i in range(rxn.GetNumReactantTemplates()):
401 tmpl=rxn.GetReactantTemplate(i)
402 tmpl.UpdatePropertyCache(False)
403 mols.append(tmpl)
404 mols.append(None)
405 for i in range(rxn.GetNumProductTemplates()):
406 tmpl = rxn.GetProductTemplate(i)
407 tmpl.UpdatePropertyCache(False)
408 mols.append(tmpl)
409
410 res = Image.new("RGBA",(subImgSize[0]*len(mols),subImgSize[1]),(255,255,255,0))
411 for i,mol in enumerate(mols):
412 if mol is not None:
413 nimg = MolToImage(mol,subImgSize,kekulize=False,**kwargs)
414 else:
415 nimg,canvas = _createCanvas(subImgSize)
416 p0 = (10,subImgSize[1]//2)
417 p1 = (subImgSize[0]-10,subImgSize[1]//2)
418 p3 = (subImgSize[0]-20,subImgSize[1]//2-10)
419 p4 = (subImgSize[0]-20,subImgSize[1]//2+10)
420 canvas.addCanvasLine(p0,p1,lineWidth=2,color=(0,0,0))
421 canvas.addCanvasLine(p3,p1,lineWidth=2,color=(0,0,0))
422 canvas.addCanvasLine(p4,p1,lineWidth=2,color=(0,0,0))
423 if hasattr(canvas,'flush'):
424 canvas.flush()
425 else:
426 canvas.save()
427 res.paste(nimg,(i*subImgSize[0],0))
428 return res
429
430
431 -def MolToQPixmap(mol, size=(300,300), kekulize=True, wedgeBonds=True,
432 fitImage=False, options=None, **kwargs):
456