RDKit:如何更改原子标签字体大小?

RDKit: How to change the atom label fontsize?

使用RDKit绘制结构时,原子标签字体大小和圆环大小比例失调。标签太小或太大或未对齐。

不幸的是,关于这个的文档很少。我找到了这个: https://rdkit.org/docs/source/rdkit.Chem.Draw.MolDrawing.html 但我不知道这是否相关以及我将如何将它们放在一起。我缺少简单实用的代码示例。

我也试过Draw.MolToQPixmap,但是我发现原子标签错位了,到目前为止我了解到原因是难以使这个跨平台一致,而且 Draw.MolToPixmap使用旧的绘图代码。我应该使用例如Draw.MolToImage 代替。但是有类似 Draw.MolToFile 的字体太小了。我不确定这是否也是一个跨平台问题(我在 Win10 上)。因此,解决方案是简单地设置字体大小,但是如何设置呢?

我知道有一个 RDKit 邮件列表,我在那里问了这个问题,到目前为止还没有答案。在这里,可能会有更广泛的受众,我可以附上图片进行说明。

代码:

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

结果:(使用Draw.MolToFile,对齐正常,但原子标签太小)

结果:(使用Draw.MolToQPixmap,未对齐and/or字体对于小图片来说太大)

编辑:(根据@Oliver Scott 的建议)

我使用相同的字体大小获得了 3 倍的相同输出。一定是我犯了个愚蠢的错误或误会了。

代码:

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)

结果:

6.0
12.0
24.0

较新的 RDKit 绘图代码比这些旧函数更灵活。尝试使用 rdMolDraw2D drawing code. You can set the options for drawing as below. The documentation 有可用选项的列表:

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

默认最小字体大小为 12,最大为 40。

结果:

要进入 PIL 图像,您可以这样做:

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.

感谢@Oliver Scott 的帮助,我终于得到了我想要的东西: 显然,字体大小是相对的(默认为 0.5),而不是绝对的点数,至少在我使用的 RDKit 2020.03 中是这样。也许这在 RDKit 2020.09 中有所改变?

代码:(获取 PNG 文件)

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)

结果:

代码:(获取 QPixmap,例如 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

您可以使用 SetPreferCoordGenCompute2DCoords

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

你得到这张 PIL 图片

2020.09 可以用,但我没有在 2020.03 测试它。