首页 > 解决方案 > 用没有直方图的地毯复制 distplot

问题描述

当我浏览在线教程和\或一般文章时,当我遇到使用 Seaborn distplot 图的图时,我会使用 histplot 或 displot 重新创建它。

我这样做是因为 distplot 已被弃用,并且我想使用更新的标准重新编写代码。

我正在阅读这篇文章: https ://www.kite.com/blog/python/data-analysis-visualization-python/

并且有一个部分使用 distplot 其输出我无法复制。

这是我要复制的代码部分:

col_names = ['StrengthFactor', 'PriceReg', 'ReleaseYear', 'ItemCount', 'LowUserPrice', 'LowNetPrice']
fig, ax = plt.subplots(len(col_names), figsize=(8, 40))
for i, col_val in enumerate(col_names):
    x = sales_data_hist[col_val][:1000]
    sns.distplot(x, ax=ax[i], rug=True, hist=False)
    outliers = x[percentile_based_outlier(x)]
    ax[i].plot(outliers, np.zeros_like(outliers), 'ro', clip_on=False)

    ax[i].set_title('Outlier detection - {}'.format(col_val), fontsize=10)
    ax[i].set_xlabel(col_val, fontsize=8)

plt.show()

distplot 本身和轴变量都不再使用。代码,现在,运行。

简而言之,我要做的就是在不使用已弃用代码的情况下复制上面代码的确切输出(地毯图、代表已删除值的红点等)。

我尝试了 displot 和 histplot 的各种组合,但我无法以任何其他方式获得完全相同的输出。

标签: pythonmatplotlibseaborn

解决方案


sns.kdeplot()函数显示可用的 kde 曲线distplot。(其实distplot只是内部调用kdeplot)。同样,还有sns.rugplot()展示地毯。

这是一个更容易复制 iris 数据集的示例:

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

def percentile_based_outlier(data, threshold=95):
    diff = (100 - threshold) / 2
    minval, maxval = np.percentile(data, [diff, 100 - diff])
    return (data < minval) | (data > maxval)

iris = sns.load_dataset('iris')
col_names = [col for col in iris.columns if iris[col].dtype == 'float64']  # the numerical columns
fig, axs = plt.subplots(len(col_names), figsize=(5, 12))
for ax, col_val in zip(axs, col_names):
    x = iris[col_val]
    sns.kdeplot(x, ax=ax)
    sns.rugplot(x, ax=ax, color='C0')
    outliers = x[percentile_based_outlier(x)]
    ax.plot(outliers, np.zeros_like(outliers), 'ro', clip_on=False)

    ax.set_title(f'Outlier detection - {col_val}', fontsize=10)
    ax.set_xlabel('')  # ax[i].set_xlabel(col_val, fontsize=8)
plt.tight_layout()
plt.show()

模拟 sns.displot(hist=False, rug=True)

要使用displot,可以通过 将数据帧转换为“长格式”pd.melt()。可以通过调用的自定义函数添加异常值g.map_dataframe(...)

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

def percentile_based_outlier(data, threshold=95):
    diff = (100 - threshold) / 2
    minval, maxval = np.percentile(data, [diff, 100 - diff])
    return (data < minval) | (data > maxval)

def show_outliers(data, color):
    col_name = data['variable'].values[0]
    x = data['value'].to_numpy()
    outliers = x[percentile_based_outlier(x)]
    plt.plot(outliers, np.zeros_like(outliers), 'ro', clip_on=False)
    plt.xlabel('')

iris = sns.load_dataset('iris')
col_names = [col for col in iris.columns if iris[col].dtype == 'float64']  # the numerical columns
iris_long = iris.melt(value_vars=col_names)
g = sns.displot(data=iris_long, x='value', kind='kde', rug=True, row='variable',
                height=2.2, aspect=3,
                facet_kws={'sharey': False, 'sharex': False})
g.map_dataframe(show_outliers)

显示异常值


推荐阅读