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

如何在Seaborn/Matplotlib中指定特定概率密度的Contour Level

如何在Seaborn/Matplotlib中指定特定概率密度的Contour Level

我懂你需求了——你想要的不是Seaborn默认那种等间隔的密度等高线,而是能精准对应数据占比的等高线(比如刚好圈住50%的样本)对吧?找这个方法确实有点绕,我给你一个直接可行的方案,用Scipy的KDE工具配合Seaborn就能实现:

核心思路是:先手动计算联合概率密度的分布,找到对应目标概率的密度阈值,再把这个阈值传给Seaborn的kdeplot作为levels参数,这样画出来的等高线就刚好包含你指定比例的数据。

下面是修改后的完整代码,直接替换你原来的代码就行:

import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde

# 你的数据(这里保留你的示例数据,实际用真实数据替换即可)
np.random.seed(0)
x = np.random.randn(100)
y = np.random.randn(100)

# --------------------------
# 关键步骤:计算目标概率对应的密度阈值
# --------------------------
# 创建联合概率密度估计器
kde = gaussian_kde(np.vstack([x, y]))

# 生成和你坐标轴范围匹配的网格点(100j是网格分辨率,数字越大越精准)
xmin, xmax = 0, 20
ymin, ymax = 0, 17.5
xi, yi = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]
positions = np.vstack([xi.ravel(), yi.ravel()])

# 计算每个网格点的密度值
density = kde(positions).reshape(xi.shape)

# 把密度值扁平化,按从高到低排序
density_flat = density.ravel()
sorted_density = np.sort(density_flat)[::-1]

# 计算累积概率:密度高的区域对应数据更集中,累加后除以总密度(即1)得到占比
cumulative_prob = np.cumsum(sorted_density) / np.sum(sorted_density)

# 设定你想要的目标概率,比如50%
target_prob = 0.5
# 找到第一个累积概率达标时对应的密度阈值
threshold = sorted_density[np.argmax(cumulative_prob >= target_prob)]

# --------------------------
# 画图部分,和你原来的逻辑一致,只是levels参数用我们计算的阈值
# --------------------------
sns.jointplot(x=x, y=y, kind="scatter", color='b')
# 传入阈值作为levels,如果你要多个概率(比如50%和90%),就传[threshold1, threshold2]
sns.kdeplot(x=x, y=y, color="r", levels=[threshold])

# 你的坐标轴范围设置
plt.ylim(0, 17.5)
plt.xlim(0, 20)

plt.show()

额外说明

  • 如果你需要同时画多个概率的等高线,比如50%和90%,只需要重复计算对应的threshold,把它们放进levels列表里就行。
  • 网格的分辨率(代码里的100j)可以根据需求调整,数值越大,计算出的阈值越精准,但计算速度会稍慢。
  • 这个方法的核心是直接基于你的数据分布计算,完全贴合你想要的“指定概率占比的等高线”需求,不是用默认的等间隔分割。

备注:内容来源于stack exchange,提问作者Apinorr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 07:04:50