广告位 · 页头(后台-模块管理-新建模块后替换此区域)

如何在 VS Code 中显示 RDKit 分子图像

RDKit 是一个开源的化学信息学工具包,广泛用于分子指纹计算、子结构搜索和化学空间分析。很多化学信息学的工作流都在 VS Code 中编写 Python 代码,但一个常见的困扰是:运行脚本后只能看到 SMILES 字符串或者分子对象的内存地址,没法直观地确认分子结构是否正确。其实 RDKit 自带强大的二维结构绘制能力,配合 VS Code 的预览机制,完全可以在编辑器内直接显示分子图像,不需要切换到外部图片查看器。

如何在 VS Code 中显示 RDKit 分子图像

从 SMILES 到 SVG:RDKit 的绘图基础

RDKit 提供了 rdkit.Chem.Draw 模块,其中最常用的函数是 MolToImage 和 MolToFile,它们可以把分子对象渲染成 PNG 图片。然而在 VS Code 中要直接预览图片,PNG 并不是最方便的选择,因为需要依赖系统默认图片查看器或者额外的 Markdown 预览插件。更灵活的做法是生成 SVG 矢量图。SVG 是一种基于 XML 的文本格式,可以直接嵌入到 HTML 或者用 VS Code 内置的预览功能打开。

下面的代码展示了如何从一个 SMILES 字符串生成 SVG 字符串。这里使用 Chem.MolFromSmiles 解析分子,然后调用 rdMolDraw2D.MolDraw2DSVG 进行绘制。注意 rdMolDraw2D 模块的输出是 SVG 文本,可以写入文件或者直接打印到控制台。

from rdkit import Chem
from rdkit.Chem import Draw
from rdkit.Chem.Draw import rdMolDraw2D
smiles = "CCO"  # 乙醇
mol = Chem.MolFromSmiles(smiles)
# 创建 SVG 绘图对象,设置画布尺寸
drawer = rdMolDraw2D.MolDraw2DSVG(400, 300)
# 绘制分子
rdMolDraw2D.PrepareAndDrawMolecule(drawer, mol)
# 结束绘图并获取 SVG 文本
drawer.FinishDrawing()
svg_text = drawer.GetDrawingText()
# 将 SVG 保存为文件
with open("ethanol.svg", "w", encoding="utf-8") as f:
    f.write(svg_text)
print("SVG 文件已保存")

上面的代码生成一个 400x300 像素的 SVG 文件。你可以直接在 VS Code 中右键点击文件并选择“打开预览”来查看,或者安装 SVG 预览扩展以获得更好的渲染效果。SVG 文件的优势在于可以无损缩放,而且文本格式便于检查原子坐标和绘图参数。对于一些复杂的分子,还可以通过 MolDraw2DSVG 的选项控制键长、颜色和显示氢原子等细节。

如果只是想在终端快速查看分子结构,也可以直接输出 SVG 字符串到控制台,然后复制到浏览器地址栏或者使用 data:image/svg+xml 协议。不过这种方式在 Windows 命令行下可能因为换行问题导致显示异常,建议优先写入文件。

在 VS Code 中实时预览分子的两种方案

第一种方案是利用 VS Code 的 Markdown 预览功能。Markdown 预览支持直接嵌入 HTML 标签,而 SVG 本质上是 XML 文本,可以嵌入到 HTML 中。我们可以编写一个脚本,把生成的 SVG 内容包裹进一个简单的 HTML 模板,然后输出为 .html 文件。VS Code 对 HTML 文件有内置的预览支持,按下 Ctrl+Shift+V 或者点击右上角的预览按钮即可查看。

from rdkit import Chem
from rdkit.Chem.Draw import rdMolDraw2D
def mol_to_html(smiles, width=400, height=300):
    mol = Chem.MolFromSmiles(smiles)
    if mol is None:
        return "<p>无效的 SMILES</p>"
    drawer = rdMolDraw2D.MolDraw2DSVG(width, height)
    rdMolDraw2D.PrepareAndDrawMolecule(drawer, mol)
    drawer.FinishDrawing()
    svg = drawer.GetDrawingText()
    # 将 SVG 嵌入 HTML
    html = f"""<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>分子预览</title></head>
<body style="background:white;">
{svg}
</body>
</html>"""
    return html
with open("preview.html", "w", encoding="utf-8") as f:
    f.write(mol_to_html("c1ccccc1"))  # 苯环
print("HTML 预览文件已生成")

这个方法的好处是无需任何额外插件,只要 VS Code 能打开 HTML 文件就能看到分子结构。但缺点是每次查看新分子都需要重新生成文件,而且 HTML 中的 SVG 会略微改变默认的坐标系统,可能需要调整 viewBox 属性才能完整显示。另外,Markdown 预览对嵌入的 SVG 支持较好,但直接在 HTML 文件中预览 SVG 有时会出现缩放问题,建议将 SVG 的宽度和高度属性删除,改用 style="max-width:100%;" 来保持比例。

第二种方案是使用 VS Code 的 Jupyter 扩展。如果你已经安装了 Python 和 Jupyter 核心,在 .ipynb 笔记本文件中可以直接让 RDKit 的 MolsToGridImage 返回一个 SVG 图像对象,Jupyter 会在输出单元格中自动渲染。这种方法交互性最强,适合批量查看多个分子或者在做化学反应枚举时快速浏览产物。

from rdkit import Chem
from rdkit.Chem import Draw
smiles_list = ["CCO", "CCN", "CCC", "c1ccccc1"]
mols = [Chem.MolFromSmiles(s) for s in smiles_list]
# 在 Jupyter 单元格中直接显示分子网格
img = Draw.MolsToGridImage(mols, molsPerRow=2, subImgSize=(300, 250))
img

当你在 VS Code 中创建一个 .ipynb 文件并运行上述代码时,输出区域会直接显示四个分子的二维结构网格。这是因为 Jupyter 扩展能够识别 RDKit 返回的 PIL.Image 对象或者 IPython 的 SVG 对象,并自动进行渲染。如果你希望强制使用 SVG 格式而不是 PNG,可以先用 rdMolDraw2D 生成 SVG 字符串,然后通过 IPython.display.SVG 输出,这样在缩放界面时图像不会模糊。

进阶技巧:自定义渲染样式与批量报告

RDKit 的绘图模块支持大量样式定制,比如高亮子结构、显示原子编号、调整原子颜色和键的粗细。这些功能在研究药物分子与靶点结合位点时非常有用。举一个实际场景:你需要对比一组化合物中公共骨架的原子位置,可以通过 rdMolDraw2D.PrepareAndDrawMolecule 传入高亮参数来实现。

from rdkit import Chem
from rdkit.Chem.Draw import rdMolDraw2D
smiles = "CC(=O)Oc1ccccc1C(=O)O"  # 阿司匹林
mol = Chem.MolFromSmiles(smiles)
# 高亮羧基中的碳和氧原子
highlight_atoms = []
for atom in mol.GetAtoms():
    if atom.GetSymbol() == "O" and atom.GetTotalNumHs() == 0:
        highlight_atoms.append(atom.GetIdx())
drawer = rdMolDraw2D.MolDraw2DSVG(500, 400)
# 设置高亮颜色和半径
opts = drawer.drawOptions()
opts.setHighlightColour((0.0, 0.6, 0.8, 0.6))
rdMolDraw2D.PrepareAndDrawMolecule(drawer, mol, highlightAtoms=highlight_atoms)
drawer.FinishDrawing()
svg = drawer.GetDrawingText()
with open("aspirin_highlight.svg", "w", encoding="utf-8") as f:
    f.write(svg)

上面的代码会把阿司匹林分子中所有不含氢的氧原子用半透明青色高亮显示。如果你要生成一个包含多个分子的对比图,可以不断追加 SVG 内容到一个 HTML 容器的 div 中,或者使用 MolsToGridImage 的 legends 参数添加分子名称。例如在生成一个包含 20 个候选化合物的虚拟筛选报告时,你可以循环调用绘图函数,把每个分子的 SVG 依次写入同一个 HTML 文件,再用 VS Code 的 HTML 预览一次性查看整个页面。

需要注意的是,SVG 字符串中包含 XML 声明和命名空间,在拼接到 HTML 中时要确保编码一致。如果显示乱码,可以在写入文件时指定 UTF-8 编码,并在 HTML 头部声明 meta charset="utf-8"。另一个常见的坑是 Windows 路径中的反斜杠,比如将 SVG 文件保存到 C:\Users\YourName\preview\mol.svg 时,Python 字符串中的反斜杠需要转义或使用原始字符串,例如 r"C:\Users\YourName\preview\mol.svg",否则 \U 会被当成 Unicode 转义序列导致错误。

总体来看,在 VS Code 中显示 RDKit 分子图像并不是一件复杂的事,核心思路就是让 RDKit 输出一种 VS Code 能直接预览的格式,SVG 因为兼具矢量特性和 HTML 兼容性,是最推荐的选择。如果日常使用 Jupyter 笔记本进行探索性分析,那么直接依赖 Jupyter 扩展的渲染能力更加省心。对于需要频繁批量生成分子图的场景,建议封装一个函数,自动完成 SMILES 解析、SVG 生成和 HTML 文件写入,这样每次只需一次调用就能在 VS Code 侧边预览所有结构。掌握这些方法后,你的化学信息学开发流程会流畅很多。

广告位 · 文章底部(后台-模块管理替换此区域)