【问题标题】:RDKit: How to change the atom label fontsize?RDKit:如何更改原子标签字体大小?
【发布时间】:2020-11-13 08:57:12
【问题描述】:

使用 RDKit 绘制结构时,原子标签字体大小和环大小没有很好的比例。标签太小或太大或未对齐。

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

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

我知道有一个 RDKit 邮件列表,到目前为止我已经在其中提出了这个问题而没有答案。在 SO 上,可能有更广泛的受众,我可以附上图片进行说明。

代码:

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,对齐ok,但原子标签太小)

结果:(使用Draw.MolToQPixmap,未对齐和/或小图片字体太大)

编辑:(在@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

【问题讨论】:

    标签: font-size rdkit cheminformatics


    【解决方案1】:

    较新的 RDKit 绘图代码比这些旧函数更灵活。尝试使用rdMolDraw2D 绘图代码。您可以如下设置绘图选项。 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.
    

    【讨论】:

    • 谢谢你的榜样!实际上,我需要一个用于 PyQt QTableWidget 的 QPixmap 图像。如果我有一个 PIL 图像(通过 Draw.MolToImage),我可以将它转换为 QPixmap。那么,任何想法如何将 PNG 转换为 PIL 或 QPixmap?实际上,最后我不想将图像保存到磁盘,而只是将其显示在表格中。
    • 查看上面的编辑,这行得通吗?这样可以避免将任何内容写入磁盘。
    • 出于某种原因d.drawOptions().minFontSize = 22 不会导致字体大小增加,而d.SetFontSize(22) 会。感谢您提供 PNG 到 PIL 例程,我自己不会找到这个。
    • 啊奇怪,也许我们使用不同的 RDKit 版本。我没有注意到SetFontSize 函数,这可能是更改字体大小的更清洁的解决方案。如果它对您有帮助,如果您能将答案标记为已接受,我将不胜感激。谢谢!
    • 嗯,很遗憾,问题还没有解决。我正在使用 RDKit 2020.03 我无法重现它:我第一次运行脚本时它可能是更大的字体大小,但是当第二次运行时,设置不同的字体大小,大小将保持不变.. . 我一定还是做错了什么。
    【解决方案2】:

    您可以使用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 测试。

    【讨论】:

    • 谢谢。你的例子说明了什么?调整到结构的 p 参考方向,从而更好地对齐原子标签?但是使用Draw.MolToImage() 更改字体大小呢?
    • @theozh 这只是 RDKit 以良好比例获得更好图像的方法。我只是想,这就是你想要的。 MolToImage() 没有更改字体大小的选项。
    • 谢谢@rapelpy,这也很有帮助。实际上,我指的是原子标签相对于环的对齐方式(在Draw.MolToQPixmap() 的情况下),而不是画布上结构的对齐方式。我希望您的建议也可以与rdMolDraw2D.MolDraw2DCairo() 一起使用。您的定向结构实际上看起来更好。
    【解决方案3】:

    感谢@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
    

    【讨论】:

      猜你喜欢
      • 2011-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-05
      • 2022-09-28
      相关资源
      最近更新 更多