如何基于Scikit-learn核密度估计绘制极坐标等高线图?
如何构造极坐标等高线图的Z参数以绘制蛋白角度的联合核密度图
问题核心
你之前的代码仅分别计算了旋转角和倾斜角的一维核密度,而极坐标等高线图需要的是这两个变量的二维联合核密度,并非一维密度的简单线性组合,这是导致结果与预期不符的根本原因。
解决方案步骤
要正确生成极投影的等高线图,需要拟合两个角度的二维联合分布,再基于二维网格计算密度值作为Z参数:
- 将旋转角与倾斜角组合成二维数据集
- 使用Scikit-learn的
KernelDensity拟合二维数据 - 生成极坐标对应的二维网格(注意角度单位转换)
- 计算网格每个点的联合密度值,重塑为网格形状作为Z
- 用Matplotlib绘制极投影的等高线图
完整代码示例
import numpy as np import matplotlib.pyplot as plt from sklearn.neighbors import KernelDensity # 假设已加载数据:rotation_angles、tiltangles 均为 shape=(2031,) 的数组 # 1. 构造二维联合数据集 data_2d = np.vstack([rotation_angles, tiltangles]).T # shape=(2031, 2) # 2. 拟合二维高斯核密度 kde = KernelDensity(kernel='gaussian', bandwidth=10).fit(data_2d) # 3. 生成极坐标网格 # 旋转角(极角θ)范围0-360度,倾斜角(极径r)根据实际数据范围调整 theta = np.linspace(0, 360, 100) r = np.linspace(np.min(tiltangles), np.max(tiltangles), 100) theta_grid, r_grid = np.meshgrid(theta, r) # 4. 计算网格点的联合密度值 grid_points = np.vstack([theta_grid.ravel(), r_grid.ravel()]).T log_dens = kde.score_samples(grid_points) Z = np.exp(log_dens).reshape(theta_grid.shape) # 5. 绘制极投影等高线图 fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}) # Matplotlib极坐标要求极角为弧度,转换角度单位 theta_rad = np.deg2rad(theta_grid) contour = ax.contourf(theta_rad, r_grid, Z, cmap='viridis') plt.colorbar(contour, label='Kernel Density') ax.set_title('Joint KDE of Protein Rotation & Tilt Angles') plt.show()
关键细节说明
- 二维KDE才能准确反映两个角度变量的关联关系,一维KDE的组合无法体现变量间的相关性
- 调整
bandwidth参数优化密度平滑度:带宽过小会导致密度图噪声大,过大则会丢失细节 - 若你的倾斜角范围不是0-90度,需修改
r的linspace参数匹配实际数据的最小/最大值 - Matplotlib的极投影默认极角从x轴正方向逆时针计算,需确保旋转角的定义与该逻辑匹配
内容的提问来源于stack exchange,提问作者hutchcha
相关产品推荐
相关产品推荐

