0
votes

RDKit: Comment changer la taille de la police de l'étiquette atomique?

Lorsque vous dessinez des structures avec RDKit, la taille de la police de l'étiquette de l'atome et la taille de l'anneau ne sont pas dans une bonne proportion. Les étiquettes sont soit trop petites, soit trop grandes ou mal alignées.

Malheureusement, la documentation à ce sujet est maigre. J'ai trouvé ceci: https://rdkit.org/docs/source/rdkit.Chem.Draw.MolDrawing.html Mais je ne sais pas si cela est lié et comment je devrais le mettre ensemble. Il me manque des exemples de code pratiques simples.

J'ai aussi essayé Draw.MolToQPixmap , mais là, j'ai constaté que les étiquettes d'atome étaient mal alignées et jusqu'à présent, j'ai appris que la raison est la difficulté de rendre cette multiplateforme cohérente et que Draw.MolToPixmap utilise un ancien code de dessin. Je devrais utiliser par exemple Draw.MolToImage place. Mais là comme avec Draw.MolToFile la taille de la police est tout simplement trop petite. Je ne suis pas sûr qu'il s'agisse également d'un problème multiplateforme (je suis sur Win10). Donc, la solution serait de simplement définir la taille de la police, mais comment?

Je sais qu'il existe une liste de diffusion RDKit où j'ai déjà posé cette question sans réponse pour l'instant. Ici sur SO, il y a peut-être un public plus large et je peux joindre des images à titre d'illustration.

Code:

6.0
12.0
24.0

Résultat: (en utilisant Draw.MolToFile , alignement ok, mais étiquettes d'atome trop petites)

entrez la description de l'image ici

Résultat: (en utilisant Draw.MolToQPixmap , mal aligné et / ou police trop grande pour les petites images)

entrez la description de l'image ici

entrez la description de l'image ici

Edit: (avec la suggestion de @Oliver Scott)

J'obtiens 3 fois la même sortie avec la même taille de police. Je dois être une erreur stupide ou un malentendu quelque part.

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)

Résultat:

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

entrez la description de l'image ici


0 commentaires

3 Réponses :


2
votes

Le nouveau code de dessin RDKit est plus flexible que ces anciennes fonctions. Essayez d'utiliser le code de dessin rdMolDraw2D . Vous pouvez définir les options de dessin comme ci-dessous. La documentation contient une liste des options disponibles:

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.

La taille de police minimale par défaut est 12 et la taille maximale est de 40.

Résultat:

RDKit molécule PNG

Pour entrer dans une image PIL, vous pouvez le faire comme ceci:

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


10 commentaires

Merci pour votre exemple! En fait, j'ai besoin d'une image QPixmap pour un PyQt QTableWidget .... Si j'ai une image PIL (via Draw.MolToImage), je pourrais la convertir en QPixmap. Alors, avez-vous des idées sur la façon d'obtenir le PNG dans PIL ou QPixmap? En fait, à la fin, je ne veux pas enregistrer les images sur le disque, mais simplement les afficher dans un tableau.


Voir les modifications ci-dessus, cela fonctionne-t-il? De cette façon, vous évitez d'écrire quoi que ce soit sur le disque.


pour une raison quelconque, d.drawOptions().minFontSize = 22 n'entraîne pas une augmentation de la d.SetFontSize(22) , contrairement à d.SetFontSize(22) . Merci pour la routine PNG à PIL, je n'aurais pas trouvé ça par moi-même.


Ah étrange peut-être que nous utilisons différentes versions de RDKit. Je n'ai pas remarqué les fonctions SetFontSize , c'est probablement une solution plus propre pour changer la taille de la police. Je vous serais reconnaissant de bien vouloir marquer la réponse comme acceptée si elle vous a aidé du tout. Merci!


hmmm, malheureusement, le problème n'est pas encore résolu. J'utilise RDKit 2020.03 Je ne parviens pas à le reproduire: la première fois que j'exécute le script, il peut s'agir d'une taille de police plus grande, mais lors de la deuxième exécution, en définissant une taille de police différente, la taille restera la même. Je dois encore faire quelque chose de mal.


hmmm, j'utilise RDKit 2020.09.1 est-il possible de partager un extrait de votre script?


cela pourrait-il être un problème de version? Je n'ai pas trouvé de documentation 2020.03 à vérifier. Sur la page RDKit, je ne vois que la documentation 2020.09.01 ... pas de lien vers la documentation 2020.03.


Continuons cette discussion en chat .


Je suppose que je l'ai trouvé. Si vous ajoutez l' print(d.FontSize()) ligne print(d.FontSize()) avant de la définir, j'ai obtenu 0.5 . Je suppose que la taille de la police est une taille relative ou un type de facteur d'échelle mais pas une taille absolue en points. Si vous définissez la taille de la police entre 0,5 et 1,5, j'obtiens un changement. Si vous tapez 12 ou 22 cela dépassera probablement le maximum ... assez étrange et mal documenté.


La taille de la police est censée être en pixels, donc je suppose par rapport à la taille de l'image? Bien que la documentation dise à peu près ...



0
votes

Grâce à l'aide de @Oliver Scott, j'ai enfin obtenu ce que je cherchais: apparemment, la taille de la police est relative (par défaut 0,5), pas absolue en points, du moins dans RDKit 2020.03, que j'utilise. Peut-être que cela a changé dans RDKit 2020.09?

Code: (pour obtenir les fichiers PNG)

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

Résultat:

entrez la description de l'image ici

Code: (pour obtenir un QPixmap, par exemple pour un PyQt QTableWidget)

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)


0 commentaires

1
votes

Vous pouvez utiliser SetPreferCoordGen et 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))

Vous obtenez cette image PIL

img

Fonctionne en 2020.09, mais je ne l'ai pas testé en 2020.03.


3 commentaires

Merci. Que montre votre exemple? Ajustement à l'orientation référencée de la structure et donc meilleur alignement des étiquettes d'atome? Mais qu'en est-il du changement de la taille de la police à l'aide de Draw.MolToImage() ?


@theozh C'est juste le moyen RDKit d'obtenir des images plus jolies dans une bonne proportion. J'ai juste pensé, c'est ce que tu voulais. MolToImage() n'a pas d'option pour changer la taille de la police.


merci @rapelpy, c'est également utile. En fait, je parlais de l'alignement de l'étiquette de l'atome par rapport aux anneaux (dans le cas Draw.MolToQPixmap() ), pas de l'alignement de la structure sur le canevas. J'espère que votre suggestion fonctionne également avec rdMolDraw2D.MolDraw2DCairo() . Votre structure orientée est en fait plus jolie.