首页 > 解决方案 > Python - 将一个 sns.histplot() 中的 bin 用于另一个 / 从 sns.histpllot() 中提取 bin 信息

问题描述

我正在尝试并排绘制 2 个直方图,第一个用于完整数据集,第二个用于数据集的子集。为了可比性,我希望两者都具有相同的类间隔,并且必须根据 Freedman-Diaconis 规则计算 bin 宽度(可能是 sns.histplot 根据 stackoverflow 答案使用的默认模式)。

我希望第一个直方图的 bin 是由 sns.histplot() 函数决定的默认值。
然后我想提取第一个图使用的 bin 间隔或断点列表,并在生成第二个直方图时将其用作参数。

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

from sklearn.datasets import load_boston
boston = load_boston()
df = pd.DataFrame(boston.data, columns=boston.feature_names)

# Histograms
f, axs = plt.subplots(1, 2, figsize=(15, 4.5))
a = sns.histplot(df['NOX'], ax=axs[0], color='steelblue')
b = sns.histplot(df.NOX[df.CRIM > 10.73], ax=axs[1], color='darkgreen')
plt.show()

问题:
1) 如何提取 sns.histplot() 使用的 bin 列表
2) 如何使用 Freedman-Diaconis 规则绘制 2 个具有相同 bin 的直方图?

标签: pythonmatplotlibseabornhistogrambins

解决方案


Seaborn 通常不提供对其计算的访问权限,它只是尝试创建可视化。但是你可以使用相同的底层函数来获得它的结果。您需要bins = np.histogram_bin_edges(..., bins='auto')(或bins='fd'强制使用 Freedman Diaconis Estimator)。然后sns.histplot(..., bins=bins)对于两者。

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston

boston = load_boston()
df = pd.DataFrame(boston.data, columns=boston.feature_names)

bins = np.histogram_bin_edges(df['NOX'], bins='auto')
f, axs = plt.subplots(1, 2, figsize=(15, 4.5))
sns.histplot(df['NOX'], bins=bins, color='steelblue', ax=axs[0])
sns.histplot(df[df['CRIM'] > 10.73]['NOX'], bins=bins, color='darkgreen', ax=axs[1])
for ax in axs:
    for p in ax.patches:
        x, w, h = p.get_x(), p.get_width(), p.get_height()
        if h > 0:
            ax.text(x + w / 2, h, f'{h / len(df) * 100:.2f}%\n', ha='center', va='center', size=8)
    ax.margins(y=0.07)
plt.show()

示例图


推荐阅读