You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Seaborn更简洁绘制单变量样本的超越概率(1-CDF)图?

Got it, let's break this down clearly. 超越概率本质就是1减去累积分布函数(CDF)(也就是P(X > x)),刚好可以基于你已经熟悉的Seaborn工具实现,结合FacetGrid做分面也非常顺畅。

先讲最简洁优雅的现代实现(推荐)

Seaborn 0.11+推出的ecdfplot直接支持绘制互补ECDF(也就是超越概率),不用手动转换,一步到位。先看单组数据的情况:

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# 构造示例单列DataFrame(如果你的数据已经是这样,跳过这步)
np.random.seed(42)
df = pd.DataFrame({'latency': np.random.normal(60, 12, 1000)})

# 绘制超越概率图
plt.figure(figsize=(8, 5))
sns.ecdfplot(data=df, x='latency', complementary=True, linewidth=2)
plt.ylabel('超越概率 P(X > x)')
plt.xlabel('Latency')
plt.title('Latency 超越概率曲线')
plt.show()

这里的complementary=True就是告诉Seaborn直接绘制1 - CDF,完美契合超越概率的需求,比手动处理CDF要简洁太多。

结合FacetGrid实现分组分面的超越概率图

如果你的DataFrame有分组字段(比如不同实验场景、不同用户群体),用FacetGrid可以快速生成多子图的超越概率对比:

# 构造带分组的示例DataFrame
np.random.seed(42)
df = pd.DataFrame({
    'latency': np.concatenate([np.random.normal(50, 10, 500), 
                               np.random.normal(70, 15, 500)]),
    'group': ['场景A']*500 + ['场景B']*500
})

# 用FacetGrid分面绘制
g = sns.FacetGrid(df, col='group', height=4, aspect=1.2)
# 在每个子图上绘制互补ECDF(超越概率)
g.map(sns.ecdfplot, 'latency', complementary=True, linewidth=2)
# 统一设置轴标签和标题
g.set_axis_labels('Latency', '超越概率 P(X > x)')
g.set_titles('{col_name}')
plt.tight_layout()
plt.show()

如果你一定要基于distplot实现(兼容旧版Seaborn)

如果你的Seaborn版本较低(<0.11),还在使用distplot,可以通过绘制CDF后反转y轴并转换含义来实现:

# 单组情况
plt.figure(figsize=(8, 5))
# 绘制归一化的累积直方图(即CDF)
sns.distplot(df['latency'], kde=False, hist_kws={'cumulative': True, 'density': True})
ax = plt.gca()
# 反转y轴,将CDF转换为超越概率(1 - CDF)
ax.set_ylim(ax.get_ylim()[::-1])
ax.set_ylabel('超越概率 P(X > x)')
ax.set_xlabel('Latency')
plt.title('基于distplot的超越概率曲线')
plt.show()

# 结合FacetGrid的情况
def plot_exceedance(x, **kwargs):
    sns.distplot(x, kde=False, hist_kws={'cumulative': True, 'density': True}, **kwargs)
    ax = plt.gca()
    ax.set_ylim(ax.get_ylim()[::-1])
    ax.set_ylabel('超越概率 P(X > x)')

g = sns.FacetGrid(df, col='group', height=4, aspect=1.2)
g.map(plot_exceedance, 'latency')
g.set_axis_labels('Latency', '超越概率 P(X > x)')
g.set_titles('{col_name}')
plt.tight_layout()
plt.show()

小提示

  • 反转y轴是因为超越概率随x增大而递减,这样的视觉呈现更符合我们对“越大的x,超越它的概率越低”的直观认知。
  • 新版Seaborn更推荐使用ecdfplot/histplot替代distplot,前者的API更清晰,功能也更强大。

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

火山引擎 最新活动