You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将PNG对象添加至Pandas DataFrame并正常显示?

解决RDKit生成的PIL图像在Pandas DataFrame中无法显示的问题

你遇到的问题是因为Pandas默认不会渲染PIL图像对象,只会输出它的字符串描述(比如<PIL.PngImagePlugin.PngImageFile...>)。要让图像在DataFrame中正常显示,有两种可行方案:

方案一:将图像转为Base64编码嵌入HTML显示

这种方法通过把PIL图像转换成Base64字符串,嵌入HTML标签中,让Jupyter Notebook能够渲染图像。

修改代码如下:

import pandas as pd
import numpy as np
from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit import DataStructs
from rdkit.Chem import PandasTools
from rdkit.Chem import Draw
from rdkit.Chem.Draw import IPythonConsole
from IPython.display import HTML, display
import base64
from io import BytesIO

# 定义PIL图像转HTML的函数
def pil_to_html(img):
    buffer = BytesIO()
    img.save(buffer, format='PNG')
    img_base64 = base64.b64encode(buffer.getvalue()).decode()
    return f'<img src="data:image/png;base64,{img_base64}" style="max-width:400px;" />'

smiles_list = ['N[C@H](C(=O)O)C']
mol_list = []
for smiles in smiles_list:
    mol = Chem.MolFromSmiles(smiles)
    mol_list.append(mol)

glycine = mol_list[0]
figure_list = []

bi = {}
fp = AllChem.GetMorganFingerprintAsBitVect(glycine, 2, nBits=1024, bitInfo=bi)
prints = [(glycine, x, bi) for x in fp.GetOnBits()]
figure = Draw.DrawMorganBits(prints, molsPerRow=4, legends=[str(x) for x in fp.GetOnBits()])
figure_list.append(figure)

df = pd.DataFrame({'smiles': smiles_list[0]}, index=[0])
PandasTools.AddMoleculeColumnToFrame(df,'smiles','Molecule')
# 将图像列转为HTML格式
df['Fragments'] = df['Fragments'].apply(pil_to_html)

# 显示渲染后的DataFrame
display(HTML(df.to_html(escape=False)))

方案二:自定义Pandas对象格式化器

通过注册自定义的格式化函数,让Pandas在显示PIL图像对象时自动调用IPython的图像渲染功能。

修改代码如下:

import pandas as pd
import numpy as np
from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit import DataStructs
from rdkit.Chem import PandasTools
from rdkit.Chem import Draw
from rdkit.Chem.Draw import IPythonConsole
from IPython.display import display_png

# 定义PIL图像的显示函数
def display_pil_img(val):
    if isinstance(val, Draw.PIL.PngImagePlugin.PngImageFile):
        display_png(val)

# 设置Pandas显示选项
pd.set_option('display.max_colwidth', None)
# 注册对象格式化器
pd.io.formats.formatters.set_formatter('object', display_pil_img)

smiles_list = ['N[C@H](C(=O)O)C']
mol_list = []
for smiles in smiles_list:
    mol = Chem.MolFromSmiles(smiles)
    mol_list.append(mol)

glycine = mol_list[0]
figure_list = []

bi = {}
fp = AllChem.GetMorganFingerprintAsBitVect(glycine, 2, nBits=1024, bitInfo=bi)
prints = [(glycine, x, bi) for x in fp.GetOnBits()]
figure = Draw.DrawMorganBits(prints, molsPerRow=4, legends=[str(x) for x in fp.GetOnBits()])
figure_list.append(figure)

df = pd.DataFrame({'smiles': smiles_list[0]}, index=[0])
PandasTools.AddMoleculeColumnToFrame(df,'smiles','Molecule')
df['Fragments'] = figure_list

# 直接显示DataFrame,图像会被自动渲染
df

注意事项

  • 两种方案都需要在Jupyter Notebook/JupyterLab环境下运行,因为依赖IPython的渲染能力。
  • 方案一中的style="max-width:400px;"可以根据需要调整图像显示大小。

内容的提问来源于stack exchange,提问作者Andre Pimentel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 21:35:25