RDKit: как изменить размер шрифта метки atom?

#font-size #rdkit #cheminformatics

#размер шрифта #rdkit #химинформатика

Вопрос:

При рисовании структур с помощью RDKit размер шрифта метки atom и размер кольца не находятся в хорошей пропорции. Метки либо слишком маленькие, либо слишком большие, либо смещены.

К сожалению, документация об этом скудна. Я нашел это: https://rdkit.org/docs/source/rdkit.Chem.Draw .MolDrawing.html Но я не знаю, связано ли это между собой и как я должен был бы собрать все воедино. Мне не хватает простых практических примеров кода.

Я тоже пытался Draw.MolToQPixmap , но там я столкнулся с тем, что метки atom смещены, и до сих пор я узнал, что причиной является трудность сделать эту кроссплатформенную согласованность и, кроме 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 , выравнивание в порядке, но слишком маленькие метки атома)

введите описание изображения здесь

Результат: (использование 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
  

введите описание изображения здесь

Ответ №1:

Новый код рисования RDKit более гибкий, чем эти старые функции. Попробуйте использовать код rdMolDraw2D чертежа. Вы можете установить параметры для рисования, как показано ниже. В документации есть список доступных опций:

 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.

Результат:

Молекула RDKit PNG

Чтобы попасть в 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.
  

Комментарии:

1. Спасибо за ваш пример! На самом деле, мне нужно изображение QPixmap для PyQt QTableWidget…. Если у меня есть PIL-изображение (через Draw. MolToImage) Я мог бы преобразовать его в QPixmap. Итак, есть идеи, как перевести PNG в формат PIL или QPixmap? На самом деле, в конце я не хочу сохранять изображения на диск, а просто отображать их в таблице.

2. Смотрите выше правки, это работает? Таким образом, вы избегаете записи чего-либо на диск.

3. по какой-то причине d.drawOptions().minFontSize = 22 не приводит к увеличению размера шрифта, тогда d.SetFontSize(22) как делает. Спасибо за процедуру преобразования PNG в PIL, я бы не нашел это самостоятельно.

4. Странно, может быть, мы используем разные версии RDKit. Я не заметил SetFontSize функций, вероятно, это более чистое решение для изменения размера шрифта. Я был бы признателен, если бы вы могли пометить ответ как принятый, если он вам вообще помог. Спасибо!

5. хммм, к сожалению, проблема еще не решена. Я использую RDKit 2020.03, я не могу его воспроизвести: при первом запуске скрипта размер шрифта может быть больше, но при повторном запуске, установке другого размера шрифта, размер останется прежним… Должно быть, я все еще делаю что-то не так.

Ответ №2:

Благодаря помощи @Oliver Scott я наконец получил то, что искал: по-видимому, размер шрифта относительный (по умолчанию 0,5), а не абсолютный в пунктах, по крайней мере, в RDKit 2020.03, который я использую. Может быть, это изменилось в RDKit 2020.09?

Код: (для получения файлов PNGS)

 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
  

Ответ №3:

Вы можете использовать SetPreferCoordGen и 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))
  

Вы получаете это изображение PIL

img

Работает в 2020.09, но я не тестировал его в 2020.03.

Комментарии:

1. Спасибо. Что показывает ваш пример? Настройка на p-ориентированную ориентацию структуры и, следовательно, лучшее выравнивание меток атома? Но как насчет изменения размера шрифта с помощью Draw.MolToImage() ?

2. @theozh Это просто способ RDKit получать более качественные изображения в хорошей пропорции. Я просто подумал, это то, что вы хотели. MolToImage() не имеет опции для изменения размера шрифта.

3. спасибо @rapelpy, это тоже полезно. На самом деле я имел в виду выравнивание метки атома относительно колец (в Draw.MolToQPixmap() случае), а не выравнивание структуры на холсте. Я надеюсь, что ваше предложение также работает вместе с rdMolDraw2D.MolDraw2DCairo() . Ваша ориентированная структура на самом деле выглядит лучше.