当前位置:首页>python>【零基础玩转Python】Day51:常用统计图 – 直方图、箱线图、热力图,洞悉数据分布的三个视角

【零基础玩转Python】Day51:常用统计图 – 直方图、箱线图、热力图,洞悉数据分布的三个视角

  • 2026-09-10 16:05:36
【零基础玩转Python】Day51:常用统计图 – 直方图、箱线图、热力图,洞悉数据分布的三个视角

【零基础玩转Python】Day51:常用统计图 – 直方图、箱线图、热力图,洞悉数据分布的三个视角

大家好,我是[知识充电宝的灵感日记]。

昨天我们学习了 Seaborn 的基础美化,今天我们将深入三种最常用的统计图表:直方图(分布)、箱线图(离散与异常)、热力图(相关性)。掌握这些图表,你就能快速理解一个数据集的整体面貌。

今天的目标:

  • ✅ 直方图:分箱策略、核密度估计、累积分布
  • ✅ 箱线图:四分位数、异常值、分组箱线图
  • ✅ 热力图:相关矩阵、颜色映射、数值标注
  • ✅ 实战:对泰坦尼克数据集进行完整的分布与相关性分析

难度:⭐⭐(理解统计概念即可,绘图有现成函数

一、直方图(Histogram)

直方图用于展示连续变量的分布情况(频数或频率)。横轴是数值区间(bins),纵轴是落入每个区间的数据个数。

1. 基础直方图

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

plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']  
plt.rcParams['axes.unicode_minus'] = False

# 加载数据
tips = sns.load_dataset('tips')
plt.figure(figsize=(8, 4))
sns.histplot(tips['total_bill'], bins=20)
plt.title('账单金额分布(频数)')
plt.xlabel('账单金额(美元)')
plt.ylabel('频数')
plt.show()

2. 调整分箱(bins)

分箱数量直接影响直方图的表现:

fig, axes = plt.subplots(1, 3, figsize=(12, 3))
sns.histplot(tips['total_bill'], bins=5, ax=axes[0])
axes[0].set_title('bins=5 (过粗)')
sns.histplot(tips['total_bill'], bins=20, ax=axes[1])
axes[1].set_title('bins=20 (适中)')
sns.histplot(tips['total_bill'], bins=50, ax=axes[2])
axes[2].set_title('bins=50 (过细)')
plt.tight_layout()
plt.show()

3. 核密度估计(KDE):平滑分布

添加 kde=True可以绘制概率密度曲线。

sns.histplot(tips['total_bill'], bins=20, kde=True, color='skyblue')
plt.title('频数直方图 + KDE 密度曲线')
plt.show()

4. 累积分布图(CDF)

展示数据在各区间的累积比例,不依赖于分箱。

sns.histplot(tips['total_bill'], cumulative=True, stat='density', bins=30)
plt.title('累积分布函数')
plt.ylabel('累积密度')
plt.show()

5. 多组数据的直方图对比

可以用 hue参数进行分组,或使用 displot创建分面直方图。

sns.histplot(data=tips, x='total_bill', hue='time', multiple='stack', bins=20)
plt.title('按用餐时段堆叠的账单金额分布')
plt.show()

multiple 参数可选:'layer'(叠加)、'stack'(堆叠)、'dodge'(并排)、'fill'(归一化堆叠)。

二、箱线图(Boxplot)

箱线图展示数据的五数概括(最小值、Q1、中位数、Q3、最大值)以及异常值,是识别离群点的利器。

1. 基础箱线图

plt.figure(figsize=(6, 5))
sns.boxplot(y='total_bill', data=tips)
plt.title('账单金额箱线图')
plt.ylabel('账单金额(美元)')
plt.show()

图中:

  • 箱子中间线:中位数
  • 箱子下沿:第一四分位数(Q1)
  • 箱子上沿:第三四分位数(Q3)
  • 须(whisker):通常延伸到 Q1-1.5*IQR和 Q3+1.5*IQR,但不超出数据范围
  • 菱形点:异常值(超出须的范围)

2. 分组箱线图(按类别)

plt.figure(figsize=(8, 5))
sns.boxplot(x='day', y='total_bill', data=tips, palette='Set2', hue='day', legend=False)
plt.title('不同日期的账单金额分布')
plt.xlabel('星期')
plt.ylabel('账单金额')
plt.show()

3. 箱线图 + 散点叠加(stripplot 或 swarmplot)

为了看到实际数据点,可以叠加散点图:

plt.figure(figsize=(8, 5))
sns.boxplot(x='day', y='total_bill', data=tips, palette='Set2', hue='day', legend=False)
sns.stripplot(x='day', y='total_bill', data=tips, color='black', alpha=0.5, size=8)
plt.title('箱线图 + 原始数据点')
plt.show()

4. 小提琴图(Violinplot)——箱线图 + KDE

小提琴图结合了箱线图和密度曲线,能更细致地显示分布形状。

plt.figure(figsize=(8, 5))
sns.violinplot(x='day', y='total_bill', data=tips, palette='muted', hue='day', legend=False)
plt.title('小提琴图:箱线图 + 密度曲线')
plt.show()

三、热力图(Heatmap)

热力图常用于可视化相关性矩阵,也可以用颜色表示任意二维数值表的大小。

1. 相关性热力图

# 选择数值列
numeric_cols = tips.select_dtypes(include=[np.number])
corr = numeric_cols.corr()

plt.figure(figsize=(6, 5))
sns.heatmap(corr, annot=True, cmap='coolwarm', center=0, square=True)
plt.title('数值变量相关性热力图')
plt.show()

  • annot:是否显示数值
  • cmap:颜色映射('coolwarm', 'viridis', 'RdBu' 等)
  • center=0:将颜色映射的中心设为0,适合显示正负相关
  • square:使每个单元格为正方形
  • fmt:数值格式,如 fmt='.2f'(保留两位小数)

2. 自定义颜色映射

sns.heatmap(corr, annot=True, cmap='RdYlBu_r', center=0, vmin=-1, vmax=1)

vmin和 vmax控制颜色映射的范围。

3. 热力图用于展示数据表(比如透视表结果)

# 创建透视表
pivot = tips.pivot_table(index='day', columns='time', values='total_bill', aggfunc='mean')
plt.figure(figsize=(5, 4))
sns.heatmap(pivot, annot=True, cmap='YlGnBu', fmt='.1f')
plt.title('不同星期/用餐时段的平均账单')
plt.show()

# 创建透视表
pivot = tips.pivot_table(index='day', columns='time', values='total_bill', aggfunc='mean', observed=False)
plt.figure(figsize=(5, 4))
sns.heatmap(pivot, annot=True, cmap='YlGnBu', fmt='.1f')
plt.title('不同星期/用餐时段的平均账单')
plt.show()

4. 聚类热力图(clustermap)

除了展示数值本身,clustermap 还会对行和列进行层次聚类,便于发现分组模式。

sns.clustermap(corr, annot=True, cmap='coolwarm', center=0)
plt.show()

四、实战小案例:tips数据探索

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

# 加载 tips 数据集(内置,无需联网)
tips = sns.load_dataset('tips')

# Mac 系统中文 + 负号修复
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False

# 创建画布
plt.figure(figsize=(12, 4))

# 1. 账单金额分布直方图 + KDE
plt.subplot(1, 3, 1)
sns.histplot(tips['total_bill'].dropna(), bins=30, kde=True, color='skyblue')
plt.title('账单金额分布')

# 2. 不同日期的账单箱线图(修复Seaborn警告)
plt.subplot(1, 3, 2)
sns.boxplot(x='day', y='total_bill', data=tips, palette='Set2', hue='day', legend=False)
plt.title('不同日期账单分布')

# 3. 数值列相关性热力图
plt.subplot(1, 3, 3)
num_cols = tips.select_dtypes(include=[np.number])
corr = num_cols.corr()
sns.heatmap(corr, annot=True, cmap='coolwarm', center=0)
plt.title('特征相关性热力图')

plt.tight_layout()
plt.show()

五、今日练习

  1. 加载 iris数据集,绘制 sepal_length的直方图,设置 bins=20,添加 KDE 曲线,并用不同颜色显示不同种类(hue='species')。
  2. 绘制 iris数据集中 sepal_length按 species分组的箱线图,并叠加 stripplot展示原始数据点。
  3. 计算 iris所有数值列的相关矩阵,绘制热力图,要求显示数值、使用 'coolwarm'颜色,并且中心为 0。
  4. (挑战)使用 penguins数据集,绘制一个 2×2 的子图:
    • 左上:body_mass_g的直方图(分箱20,带 KDE)
    • 右上:按 species分组的 bill_length_mm箱线图
    • 左下:所有数值列的相关性热力图
    • 右下:按 species分组的 flipper_length_mm小提琴图

六、常见错误与提示

  • 直方图 bins过少或过多:过少会掩盖分布细节,过多会产生噪声。可使用 numpy.histogram_bin_edges或 bins='auto'自动选择。
  • 箱线图异常值判断依赖于 IQR:对于偏态分布,异常值可能误判,可考虑使用对数变换后再绘图。
  • 热力图数据范围差异大:若数值不在 [-1,1] 区间(如单位不同),不适合直接用于相关性展示,应先标准化。
  • heatmap中 annot数值过多导致拥挤:可减小字体 annot_kws={'size':8}。
  • 直方图的纵轴:stat参数可以控制纵轴类型,默认为 count(频数),还可以选 'density'(密度)、'probability'(概率)、'percent'(百分比)。

七、明日预告

Day52:Pandas内置绘图 – 快速探索数据

我们将学习如何使用 Pandas 自带的绘图方法,一行代码快速生成图表,适合数据探索阶段。

最新文章

随机文章