Reputation: 25734
When drawing structures with RDKit, the atom label font size and the ring size are not in a good proportion. The labels are either too small or too large or misaligned.
Unfortunately, the documentation about this is meager. I found this: https://rdkit.org/docs/source/rdkit.Chem.Draw.MolDrawing.html But I don't know whether this is related and how I would have to put it together. I'm missing simple practical code examples.
I tried also Draw.MolToQPixmap
, but there I experienced that of the atom labels are misaligned and so far I learnt that the reason is the difficulty to make this cross-platform consistent and furthermore Draw.MolToPixmap
uses old drawing code. I should use e.g. Draw.MolToImage
instead. But there similar like with Draw.MolToFile
the font size is simply too small. I'm not sure whether this is a cross-platform issue as well (I'm on Win10). So, the solution would be to simply set the fontsize, but how?
I know that there is a RDKit mailing list where I asked this question already without an answer so far. Here on SO, there is maybe a broader audience and I can attach images for illustration.
Code:
from rdkit import Chem
from rdkit.Chem import Draw
smiles = ' FC1OC2N3C4[Si]5=C6B7C(C=CC6=CC4=CC2=CC1)C=CC=C7C=C5C=C3'
mol = Chem.MolFromSmiles(smiles)
img = Draw.MolToFile(mol,"Test.png",size=(300,150))
Result: (using Draw.MolToFile
, alignment ok, but too small atom labels)
Result: (using Draw.MolToQPixmap
, misaligned and/or font too large for small pictures)
Edit: (with the suggestion of @Oliver Scott)
I get 3 times the same output with the same fontsize. I must be a stupid mistake or misunderstanding somewhere.
Code:
from rdkit.Chem.Draw import rdMolDraw2D
from rdkit import Chem
smiles = 'FC1OC2N3C4[Si]5=C6B7C(C=CC6=CC4=CC2=CC1)C=CC=C7C=C5C=C3'
mol = Chem.MolFromSmiles(smiles)
def drawMyMol(fname, myFontSize):
d = rdMolDraw2D.MolDraw2DCairo(350, 300)
d.SetFontSize(myFontSize)
print(d.FontSize())
d.DrawMolecule(mol)
d.FinishDrawing()
d.WriteDrawingText(fname)
drawMyMol("Test1.png", 6)
drawMyMol("Test2.png", 12)
drawMyMol("Test3.png", 24)
Result:
6.0
12.0
24.0
Upvotes: 2
Views: 4302
Reputation: 1869
You can use SetPreferCoordGen
and Compute2DCoords
.
from rdkit import Chem
from rdkit.Chem import Draw
from rdkit.Chem import rdDepictor
rdDepictor.SetPreferCoordGen(True)
smiles = 'FC1OC2N3C4[Si]5=C6B7C(C=CC6=CC4=CC2=CC1)C=CC=C7C=C5C=C3'
mol = Chem.MolFromSmiles(smiles)
rdDepictor.Compute2DCoords(mol)
PILmol = Draw.MolToImage(mol, size=(300,150))
You get this PIL Image
Works in 2020.09, but I did not test it in 2020.03.
Upvotes: 1
Reputation: 25734
Thanks to the help of @Oliver Scott, I finally got what I was looking for: Apparently, the font size is relative (default 0.5), not absolute in points, at least in RDKit 2020.03, which I am using. Maybe this has changed in RDKit 2020.09?
Code: (to get PNGs files)
from rdkit.Chem.Draw import rdMolDraw2D
from rdkit import Chem
smiles = 'FC1OC2N3C4[Si]5=C6B7C(C=CC6=CC4=CC2=CC1)C=CC=C7C=C5C=C3'
mol = Chem.MolFromSmiles(smiles)
def myMolToPNG(fname, myFontSize):
d = rdMolDraw2D.MolDraw2DCairo(350, 300)
d.SetFontSize(myFontSize)
d.DrawMolecule(mol)
d.FinishDrawing()
d.WriteDrawingText(fname)
myMolToPNG("Test1.png", 0.5)
myMolToPNG("Test2.png", 1.0)
myMolToPNG("Test3.png", 1.5)
Result:
Code: (to get a QPixmap, e.g for a PyQt QTableWidget)
from rdkit.Chem.Draw import rdMolDraw2D
from rdkit import Chem
from PyQt5.QtGui import QPixmap
smiles = 'FC1OC2N3C4[Si]5=C6B7C(C=CC6=CC4=CC2=CC1)C=CC=C7C=C5C=C3'
mol = Chem.MolFromSmiles(smiles)
def myMolToQPixmap(myFontSize):
d = rdMolDraw2D.MolDraw2DCairo(350, 300)
d.SetFontSize(myFontSize)
d.DrawMolecule(mol)
d.FinishDrawing()
png = d.GetDrawingText()
pixmap = QPixmap()
pixmap.loadFromData(png)
return pixmap
Upvotes: 1
Reputation: 1783
The newer RDKit drawing code is more flexible than these older functions. Try using the rdMolDraw2D
drawing code. You can set the options for drawing as below. The documentation has a list of the available options:
from rdkit.Chem.Draw import rdMolDraw2D
from rdkit import Chem
smiles = 'FC1OC2N3C4[Si]5=C6B7C(C=CC6=CC4=CC2=CC1)C=CC=C7C=C5C=C3'
mol = Chem.MolFromSmiles(smiles)
# Do the drawing.
d = rdMolDraw2D.MolDraw2DCairo(350, 300)
d.drawOptions().minFontSize = 22
d.DrawMolecule(mol)
d.FinishDrawing()
d.WriteDrawingText('test.png')
The default minimum font size is 12 and the max is 40.
Result:
To get into a PIL image you could do it like this:
from PIL import Image
import io
# Change the last line of the above to get a byte string.
png = d.GetDrawingText()
# Now read into PIL.
img = Image.open(io.BytesIO(png))
# Now you can do whatever you need to do with the PIL image.
Upvotes: 2