Question: I've noticed that when I create an image from a molecule in RDKit, the size argument leads to inconsistent scaling of the bond width and element labels. The bigger the size, the thinner the lines and the smaller the element labels. I've run a test by generating an image for the same molecule using MolToImage at progressively bigger sizes. I rescaled those images to size=(600,600) and then concatenated them into a GIF. This is the result.  Here's my code from glob import glob from rdkit import Chem from rdkit.Chem import Draw from PIL import Image,ImageDraw,ImageFont def make_frames_from_smi(smi): for i in range(10): s = (i+3)*100 mol = Chem.MolFromSmiles(smi) img = Draw.MolToImage(mol,size=(s,s)) img = img.resize((600,600)) draw = ImageDraw.Draw(img) text = '%d: Initial Size: (%d,%d)'%(i+1,s,s) font_size = 40 font = ImageFont.truetype("arial.ttf", font_size) # Use your desired font # Calculate text position image_width, image_height = img.size text_x = (image_width - (bbox[2] - bbox[0])) // 2 text_y = 20 # Adjust the vertical position as needed draw.text((text_x, text_y), text, font=font, fill='black') img.save('%03dtest.png'%i) def make_gif_from_frames(paths): frames_paths = glob(paths) frames = [Image.open(imgp) for imgp in frames_paths] frames[0].save("mols.gif", format="GIF", append_images=frames, save_all=True, duration=500, loop=False) # make RDKit mol obj. smi = 'CN(C)CC1CCCCC1(C2=CC(=CC=C2)OC)O' make_frames_from_smi(smi) make_gif_from_frames('*.png')  Is this expected behaviour? Is the bond width held constant for a certain absolute value of pixels? How can I generate these images with consistent proportions regardless of width/height of pixels?

Answer: OK found , I hope , two solutions ??? First one, using Draw.rdMolDraw2D.MolDraw2DCairo: from glob import glob from rdkit import Chem from rdkit.Chem import Draw from PIL import Image from io import BytesIO def make_frames_from_smi(smi): mol = Chem.MolFromSmiles(smi) for i in range(10): s = (i+3)*100 mol = Chem.MolFromSmiles(smi) d = Draw.rdMolDraw2D.MolDraw2DCairo(s,s) dopts = d.drawOptions() # dopts.maxFontSize=40 # dopts.minFontSize=40 dopts.maxFontSize=int(0.13*s) dopts.minFontSize=int(0.13*s) print('dopts.bondLineWidth : ', dopts.bondLineWidth) #default is 2.0 dopts.bondLineWidth=(0.007*s) print('dopts.bondLineWidth : ', dopts.bondLineWidth) #default is 2.0 d.DrawMolecule(mol, legend= '%d: Initial Size: (%d,%d)'%(i+1,s,s)) d.FinishDrawing() img = d.GetDrawingText() img_b = BytesIO() img_b.write(img) pil_img = Image.open(img_b).resize((600,600)) pil_img.save('%03dtest.png'%i) def make_gif_from_frames(paths): frames_paths = glob(paths) frames_paths.sort() print(frames_paths) frames = [Image.open(imgp) for imgp in frames_paths] frames[0].save("mols.gif", format="GIF", append_images=frames, save_all=True, duration=500, loop=False) smi = 'CN(C)CC1CCCCC1(C2=CC(=CC=C2)OC)O' make_frames_from_smi(smi) make_gif_from_frames('*.png')  result:  or using SVG, Draw.rdMolDraw2D.MolDraw2DSVG, that I like more as a pic format : import rdkit print('\n-------------------------------') print('\n rdkit Version : ', rdkit.__version__) print('\n-------------------------------') from glob import glob from rdkit import Chem from rdkit.Chem import Draw from PIL import Image,ImageDraw,ImageFont from io import BytesIO from cairosvg import svg2png from moviepy.editor import ImageClip, concatenate_videoclips def make_frames_from_smi(smi): mol = Chem.MolFromSmiles(smi) drawer= Draw.rdMolDraw2D.MolDraw2DSVG(600,600) dopts = drawer.drawOptions() for i in dir(dopts) : print(i) dopts.minFontSize = -1 dopts.maxFontSize = -1 # dopts.minFontSize = 80 # dopts.maxFontSize = 80 print('drawer.FontSize : ', drawer.FontSize()) # dopts.annotationFontScale = 0.5 dopts.addAtomIndices = True drawer.DrawMolecule(mol) drawer.FinishDrawing() svg_data = drawer.GetDrawingText() with open('dtest.svg' , 'w') as handler: handler.write(svg_data) for i in range(10): s = (i+3)*100 png = svg2png(bytestring=svg_data) img = Image.open(BytesIO(png)).convert('RGBA').resize((s,s)) img.save('%03dtest.png'%i) def make_gif_from_frames(paths): input_png_list = glob(paths) input_png_list.sort() clips = [ImageClip(i).set_duration(1) for i in input_png_list] concat_clip = concatenate_videoclips(clips, method="compose") concat_clip.write_gif("test.gif", fps=2) smi = 'CN(C)CC1CCCCC1(C2=CC(=CC=C2)OC)O' make_frames_from_smi(smi) make_gif_from_frames('*.png')  result: