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

基于核密度估计的折线图小提琴图等效:不确定性颜色编码可视化

解决方案与错误修复

错误原因分析

你遇到的LinAlgError: singular matrix是因为:

  • stats.gaussian_kde默认将输入的二维数组每一行视为一个多维样本,但你的数据结构是每个x位置对应一行10个一维y样本,直接传入整个二维数组会让KDE错误地处理成50个10维样本,维度逻辑完全错误。
  • 即使维度正确,当样本量较小(比如n=10)时,若样本分布过于集中,协方差矩阵会出现奇异情况,导致计算失败。

可视化实现思路

要实现类似小提琴图的渐变阴影(颜色深浅对应概率密度),核心是对每个x位置的y样本单独做一维核密度估计,然后将所有x位置的密度值组合成二维矩阵,用pcolormesh或contourf绘制渐变区域。

完整修正代码

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# %% 生成随机数据
x = np.linspace(0, 6*np.pi, 50)

def sin_normal(n, x):
    m1 = np.abs(np.random.lognormal(size=n, sigma=1.5))
    return np.array([np.sin(x)]*n).T + m1 + 1  # 保证y值为正

y = sin_normal(10, x)
y_mean = y.mean(axis=1) 

# 定义y轴网格(线性坐标)
ymin, ymax = y.min(), y.max()
y_grid_lin = np.linspace(ymin, ymax, 100)
# 定义y轴网格(对数坐标,适配loglog图)
y_grid_log = np.logspace(np.log10(ymin), np.log10(ymax), 100)

# %% 逐x位置计算核密度估计
# 线性坐标下的密度矩阵
Z_lin = np.zeros((len(y_grid_lin), len(x)))
for i in range(len(x)):
    y_sample = y[i, :]
    # 指定带宽方法避免奇异矩阵,silverman/scott是常用自动规则,也可手动设factor(如0.5)
    kde = stats.gaussian_kde(y_sample, bw_method='silverman')
    Z_lin[:, i] = kde(y_grid_lin)

# 对数坐标下的密度矩阵
Z_log = np.zeros((len(y_grid_log), len(x)))
for i in range(len(x)):
    y_sample = y[i, :]
    kde = stats.gaussian_kde(y_sample, bw_method='silverman')
    Z_log[:, i] = kde(y_grid_log)

# %% 绘制可视化
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))

# 线性坐标图
# 绘制密度渐变阴影
pcm = ax1.pcolormesh(x, y_grid_lin, Z_lin, cmap='Blues', alpha=0.6, shading='gouraud')
# 叠加均值线
ax1.plot(x, y_mean, 'r-', linewidth=2, label='Mean')
# 可选:绘制原始数据
ax1.plot(x, y, '-', markersize=2, alpha=0.3)
ax1.set_ylabel('Y (Linear Scale)')
ax1.legend()

# 对数坐标图
pcm_log = ax2.pcolormesh(x, y_grid_log, Z_log, cmap='Blues', alpha=0.6, shading='gouraud')
ax2.loglog(x, y_mean, 'r-', linewidth=2, label='Mean')
ax2.loglog(x, y, '-', markersize=2, alpha=0.3)
ax2.set_xlabel('X')
ax2.set_ylabel('Y (Log Scale)')
ax2.legend()

# 添加颜色条(可选,展示密度与颜色的对应关系)
fig.colorbar(pcm, ax=[ax1, ax2], label='Probability Density')

plt.tight_layout()
plt.show()

关键细节说明

  • 逐行KDE处理:对每个x对应的y样本单独计算一维KDE,确保密度估计的逻辑正确。
  • 带宽调整:通过bw_method指定带宽计算规则(silverman/scott),或手动设置bw_method=0.5这类数值缩小带宽,避免样本量小时出现奇异矩阵。
  • 渐变阴影绘制:pcolormesh的shading='gouraud'参数让颜色过渡更平滑,cmap选择合适的配色(如Blues),alpha调整透明度避免遮挡均值线。
  • 对数坐标适配:对数图中使用np.logspace生成y轴网格,保证密度估计在对数尺度下的合理性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:15:51