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

如何基于log10尺度计算并在线性尺度展示Seaborn箱线图?

问题描述

现有如下结构的DataFrame,记录了不同区域每平方千米的物品数量:

n_itemsregion
28741region_1
192region_1
3856region_2
12345region_2
0region_3
297region_3

需求是绘制箱线图展示各区域数据的分布与统计特征,具体要求:

  • 对n_items列做log10变换;
  • 基于log10(n_items)计算中位数、均值、四分位数等统计量生成Seaborn箱线图;
  • 最终箱线图以原始尺度(即10^(log10(n_items)))展示。

目前使用常规箱线图代码:

sns.boxplot(data=data,
            x='n_items',
            y='region',
            hue='region',
            ax=ax,
            palette=palette,
            legend=False,
            whis=5,
            fliersize=0.8,
            showmeans=True,
            meanprops={'marker': 'o', 'markerfacecolor': 'white', 'markeredgecolor': 'black', 'markersize': '8'}
            )

曾尝试用np.log10(data)作为数据参数后手动设置ax.set_xscale("linear"),但未成功,求可行实现方法。

解决方案

核心思路是先基于log10变换后的数据计算统计量,再将结果转换回原始尺度展示。以下提供两种可靠实现方式:

方法一:手动计算统计量绘制

  1. 处理原始数据中的0值(log10(0)无意义),添加极小偏移避免报错;
  2. 按区域分组计算log尺度下的统计量,再转换回原始尺度;
  3. 用Matplotlib手动绘制箱线图并添加均值标记、离群点。

示例代码:

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

# 构建原始数据
data = pd.DataFrame({
    'n_items': [28741, 192, 3856, 12345, 0, 297],
    'region': ['region_1', 'region_1', 'region_2', 'region_2', 'region_3', 'region_3']
})

# 处理0值,添加极小偏移
data['log_n_items'] = np.log10(data['n_items'] + 1e-6)

# 按区域计算log尺度统计量,再转换回原始尺度
stats = data.groupby('region')['log_n_items'].agg([
    'median', 'mean', lambda x: np.percentile(x, 25), lambda x: np.percentile(x, 75),
    lambda x: np.percentile(x, 100 - (5/2)), lambda x: np.percentile(x, 5/2)
]).rename(columns={
    '<lambda_0>': 'q25', '<lambda_1>': 'q75',
    '<lambda_2>': 'whis_high', '<lambda_3>': 'whis_low'
})
stats = 10 ** stats

# 提取离群点(基于log尺度范围转换回原始尺度)
outliers = []
for region in stats.index:
    region_data = data[data['region'] == region]
    log_low = np.log10(stats.loc[region, 'whis_low'])
    log_high = np.log10(stats.loc[region, 'whis_high'])
    region_outliers = region_data[(region_data['log_n_items'] < log_low) | (region_data['log_n_items'] > log_high)]['n_items']
    outliers.append(region_outliers.values)

# 绘制箱线图
fig, ax = plt.subplots()
box = ax.boxplot(
    [stats.loc[r, ['whis_low', 'q25', 'median', 'q75', 'whis_high']].values for r in stats.index],
    vert=False,
    patch_artist=True,
    whis=[0,100]
)

# 设置箱线颜色
palette = sns.color_palette()
for patch, color in zip(box['boxes'], palette):
    patch.set_facecolor(color)

# 添加均值标记
for i, region in enumerate(stats.index):
    ax.scatter(stats.loc[region, 'mean'], i+1, marker='o', facecolor='white', edgecolor='black', s=64)

# 添加离群点
for i, outlier_group in enumerate(outliers):
    ax.scatter(outlier_group, [i+1]*len(outlier_group), s=0.8)

# 设置坐标轴
ax.set_yticklabels(stats.index)
ax.set_xlabel('n_items (原始尺度)')
ax.set_ylabel('region')
plt.show()

方法二:Seaborn绘制后修改坐标轴刻度

这种方式更简洁:先基于log尺度绘制箱线图,再将x轴刻度从log值转换为原始尺度数值,视觉上直接呈现目标效果。

示例代码:

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

# 构建原始数据
data = pd.DataFrame({
    'n_items': [28741, 192, 3856, 12345, 0, 297],
    'region': ['region_1', 'region_1', 'region_2', 'region_2', 'region_3', 'region_3']
})

# 处理0值,添加极小偏移
data['log_n_items'] = np.log10(data['n_items'] + 1e-6)

fig, ax = plt.subplots()

# 基于log尺度绘制箱线图
sns.boxplot(data=data,
            x='log_n_items',
            y='region',
            hue='region',
            ax=ax,
            palette=sns.color_palette(),
            legend=False,
            whis=5,
            fliersize=0.8,
            showmeans=True,
            meanprops={'marker': 'o', 'markerfacecolor': 'white', 'markeredgecolor': 'black', 'markersize': '8'}
            )

# 将log刻度转换为原始尺度标签
log_ticks = ax.get_xticks()
original_ticks = 10 ** log_ticks
ax.set_xticks(log_ticks)
ax.set_xticklabels([f'{int(tick):,}' if tick.is_integer() else f'{tick:.1f}' for tick in original_ticks])

# 设置x轴标签
ax.set_xlabel('n_items (原始尺度)')
plt.show()

注意事项

  • 必须处理原始数据中的0值,通常添加极小值(如1e-6)避免log10计算报错;
  • 方法二更适合快速实现,方法一适合需要自定义统计量或展示细节的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 04:00:52