使用Python结合RDKit生成MACCS指纹并绘制热图的问题求助
使用Python结合RDKit生成MACCS指纹并绘制热图的问题求助
看起来你已经走了大半路程啦!从摩根指纹热图的经验迁移过来思路是对的,卡在MACCS指纹转距离矩阵这一步很正常,咱们一步步来解决。
首先先帮你修正现有代码里的几个小问题:
- 导入语句里有个语法错误:
from rdkit import rdBasefrom rdkit.Chem import RDConfig应该拆成两行,而且如果暂时用不到rdBase可以先去掉; - SDF路径拼接有点问题:
os.path.join(RDConfig.RDDocsDir, '/Users/emmaf/Desktop/toxicitydatamaccs_toxic.sdf')因为第二个参数是绝对路径,os.path.join会直接忽略第一个参数,直接写你的本地路径就行; - 生成分子列表时最好过滤掉无效分子(
SDMolSupplier可能返回None,比如分子解析失败),避免后续报错; - 重复导入了
AllChem,可以清理掉冗余的导入。
接下来是核心步骤:从MACCS指纹生成距离矩阵,再绘制热图。RDKit的MACCS指纹是ExplicitBitVect类型,我们可以用RDKit自带的工具直接计算距离矩阵,非常方便。
下面是修正后的完整示例代码:
# 清理后的导入语句 import matplotlib.pyplot as plt import seaborn as sns import pandas as pd import os from rdkit import Chem from rdkit.Chem import MACCSkeys from rdkit.DataManip.Metric import GetTanimotoDistMat # 直接使用你的SDF文件路径 sdf_path = '/Users/emmaf/Desktop/toxicitydatamaccs_toxic.sdf' # 读取分子并过滤无效分子(避免解析失败的分子干扰后续步骤) mols = [m for m in Chem.SDMolSupplier(sdf_path) if m is not None] # 查看前5个分子(可选操作) from rdkit.Chem.Draw import MolsToGridImage display(MolsToGridImage(mols[:5], molsPerRow=5)) # 生成MACCS指纹 maccs_fp_list = [MACCSkeys.GenMACCSKeys(x) for x in mols] # 计算Tanimoto距离矩阵(直接接收指纹列表即可) dist_matrix = GetTanimotoDistMat(maccs_fp_list) # 转换成DataFrame,给行/列加上分子名称(如果SDF里有分子名,没有就用索引代替) mol_names = [mol.GetProp('_Name') if mol.HasProp('_Name') else f'Mol_{i}' for i, mol in enumerate(mols)] dist_df = pd.DataFrame(dist_matrix, index=mol_names, columns=mol_names) # 绘制热图 plt.figure(figsize=(12, 10)) sns.heatmap(dist_df, cmap='viridis', annot=False, fmt='.2f') plt.title('MACCS Fingerprint Tanimoto Distance Heatmap') plt.xlabel('Molecules') plt.ylabel('Molecules') plt.show()
关键步骤说明:
- 过滤无效分子:避免因为解析失败的分子导致指纹生成时抛出错误;
- 计算距离矩阵:
GetTanimotoDistMat是RDKit专门用于计算指纹距离的工具,直接接收指纹列表就能返回对称的距离矩阵,完美适配热图需求; - DataFrame转换:给矩阵的行和列加上分子名称,能让热图的可读性大幅提升;
- 热图绘制:调整
figsize可以让图更清晰,annot=False是为了避免分子数量多时热图过于拥挤,如果你需要显示具体的距离数值,可以改成annot=True。
如果想生成相似性矩阵而非距离矩阵,只需要把GetTanimotoDistMat换成GetTanimotoSimMat就行,热图的颜色逻辑会变成“相似性越高颜色越深”。
如果运行时仍有问题,可以先检查:
- RDKit版本是否正常(可以用
from rdkit import rdBase; print(rdBase.rdkitVersion)查看); - SDF文件是否能正常解析(打印
len(mols)看看有效分子数量); - 若分子数量过多,可先取一小部分测试热图效果。
备注:内容来源于stack exchange,提问作者Emma Fath
相关产品推荐
相关产品推荐

