【问题标题】:How to make a grouped histogram with consistent and nicely aligned bins?如何制作具有一致且对齐良好的箱的分组直方图?
【发布时间】:2020-07-10 13:04:34
【问题描述】:

我想制作存储在pandasDataFrame 中的数据直方图,其中直方图根据该数据框中的另一列分为两组(我们称其为 target 列,可以是 1或 0)。我无法让两组的垃圾箱以合理的方式对齐。

这是我目前所拥有的:

def fun_histByTarget(df, cols, target):
    target = df[target]
    if isinstance(cols, str):
        cols = [cols]
    fig = plt.figure(figsize=(18, 5 * ((len(cols) + 1) // 2)), dpi= 80)
    for i in range(len(cols)):
        sp = fig.add_subplot((len(cols) + 1) // 2, 2, i + 1)
        col = df[cols[i]].copy()
        sp.hist(col[target==0], color='red',  alpha=.3, label='target = 0', align='left')
        sp.hist(col[target==1], color='blue', alpha=.3, label='target = 1', align='left')
        sp.legend()
        sp.set_title(cols[i])

这是结果:

fun_histByTarget(test, 'integer_col', 'target')

我尝试过手动添加垃圾箱

bins = np.linspace(col.values.min(), col.values.max(), 10)

但这无济于事。结果箱的选择非常奇怪,因此直方图的某些条完全位于两个整数值之间,即使所有数据都是整数。这可能是因为我硬编码了 10 个 bin。但是自动选择正确数量的垃圾箱确实很困难。有没有更好的方法来做到这一点?

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    要为两者获得相同的直方图 bin,只需使用具有完全相同边界的 bins= 参数即可。因此,目前还不清楚为什么您的测试不起作用。 (如果没有看到使用的确切代码,很难说。)

    除此之外,列名“integer_col”暗示该列只有整数。直方图主要用于处理连续数据。如果您只有整数,并且您将 bin 边界创建为np.linspace(1, 7, 10),那么在[1.0, 1.667, 2.333, 3.0, 3.667, 4.333, 5.0, 5.667, 6.333, 7.0] 将有 9 个边界奇怪的 bin。因此,整数值 1 将落在第一个 bin 中,值 2 在第二个 bin 中,值 3 在第三个或第四个中(取决于浮点舍入误差),......更方便的 bin 选择是@987654326 @ 如下面的代码。 (我还将align='left' 更改为默认的align='mid' 以使条形图与其对应值位于同一位置。)

    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    
    def fun_histByTarget(df, cols, target):
        target = df[target]
        if isinstance(cols, str):
            cols = [cols]
        fig = plt.figure(figsize=(18, 5 * ((len(cols) + 1) // 2)), dpi=80)
        for i in range(len(cols)):
            ax = fig.add_subplot((len(cols) + 1) // 2, 2, i + 1)
            col = df[cols[i]]
            bins = np.arange(col.min() - 0.5, col.max() + 0.5001, (col.max() - col.max()) // 20 + 1)
            ax.hist(col[target == 0], bins=bins, color='red', alpha=.3, label='target = 0', align='mid')
            ax.hist(col[target == 1], bins=bins, color='blue', alpha=.3, label='target = 1', align='mid')
            ax.legend()
            ax.set_title(cols[i])
    
    target = np.random.randint(0, 2, 100)
    integer_col = np.where(target == 0, np.random.randint(1, 7, target.size), np.random.randint(1, 6, target.size))
    test = pd.DataFrame({'integer_col': integer_col, 'target': target})
    fun_histByTarget(test, 'integer_col', 'target')
    plt.show()
    

    如果您想避免重叠条形图,条形图有更多选项,但您需要在单独的步骤中计算计数(例如,使用np.hist,或通过pd.cut)。

    【讨论】:

      猜你喜欢
      • 2016-10-05
      • 2012-10-03
      • 1970-01-01
      • 2011-04-15
      • 2016-01-24
      • 1970-01-01
      • 1970-01-01
      • 2022-12-21
      • 2012-08-27
      相关资源
      最近更新 更多