gpt4 book ai didi

pandas - 在直方图的相对 bin 上叠加箱线图

转载 作者:行者123 更新时间:2023-12-05 05:49:54 24 4
gpt4 key购买 nike

以数据集'tip'为例

<表类="s-表"><头>total_bill提示吸烟者<日>日 <次>次 大小<正文>16.991.01没有太阳晚餐210.341.66没有太阳晚餐321.013.50没有太阳晚餐323.683.31没有太阳晚餐224.593.61没有太阳晚餐4

我想做的是表示变量“total_bill”的分布,并将其每个容器与链接的变量“tip”的分布相关联给它。在此示例中,此图旨在回答以下问题:“客户留下的小费随他们支付的账单的分布情况如何?”

我已经或多或少地实现了我想要获得的图表(但是有一个问题,最后我解释它是什么)。
而我采用的流程是这样的:

  1. 将“total_bill”分成多个箱子。

    tips['bins_total_bill'] = pd.cut(tips.total_bill, 10)
    tips.head()
    <表类="s-表"><头>total_bill提示吸烟者<日>日 <次>次 大小bins_total_bill<正文>16.991.01没有太阳晚餐2(12.618, 17.392]10.341.66没有太阳晚餐3(7.844, 12.618]21.013.50没有太阳晚餐3(17.392, 22.166]23.683.31没有太阳晚餐2(22.166, 26.94]24.593.61没有太阳晚餐4(22.166, 26.94]
  2. 使用以下内容创建 pd.Series:
    索引:total_cost bins 的 pd.interval
    值:出现次数

    s = tips['bins_total_bill'].value_counts(sort=False)
    s
(3.022, 7.844]       7
(7.844, 12.618] 42
(12.618, 17.392] 68
(17.392, 22.166] 51
(22.166, 26.94] 31
(26.94, 31.714] 19
(31.714, 36.488] 12
(36.488, 41.262] 7
(41.262, 46.036] 3
(46.036, 50.81] 4
Name: bins_total_bill, dtype: int64
  1. 结合barplot和poxplot

    fig, ax1 = plt.subplots(dpi=200)
    ax2 = ax1.twinx()

    sns.barplot(ax=ax1, x = s.index, y = s.values)
    sns.boxplot(ax=ax2, x='bins_total_bill', y='tip', data=tips)
    sns.stripplot(ax=ax2, x='bins_total_bill', y='tip', data=tips, size=5, color="yellow", edgecolor='red', linewidth=0.3)

    #Title and axis labels
    ax1.tick_params(axis='x', rotation=90)
    ax1.set_ylabel('Number of bills')
    ax2.set_ylabel('Tips [$]')
    ax1.set_xlabel("Mid value of total_bill bins [$]")
    ax1.set_title("Tips ~ Total_bill distribution")

    #Reference lines average(tip) + add yticks + Legend
    avg_tip = np.mean(tips.tip)
    ax2.axhline(y=avg_tip, color='red', linestyle="--", label="avg tip")
    ax2.set_yticks(list(ax2.get_yticks() + avg_tip))
    ax2.legend(loc='best')

    #Set labels axis x
    ax1.set_xticklabels(list(map(lambda s: round(s.mid,2), s.index)))

    barplot and poxplot together

不得不说,这张图有问题!由于 x 轴是分类的,例如,我不能在“total_bill”的平均值处添加一条垂直线。

如何解决这个问题以获得正确的结果?我也想知道是否有比我采用的方法更正确、更精简的方法。

最佳答案

我想到了这个方法,它比上一个更紧凑(它可能可以做得更好)并且克服了在x轴上缩放的问题。

  1. 我将“total_bill”拆分为 bin 并将该列添加到 Df

    tips['bins_total_bill'] = pd.cut(tips.total_bill, 10)
  2. 按之前创建的 bin 对列“tip”进行分组

    obj_gby_tips = tips.groupby('bins_total_bill')['tip']
    gby_tip = dict(list(obj_gby_tips))
  3. 创建字典:
    keys:每个bins间隔的中点
    values: gby tips for each interval

    mid_total_bill_bins = list(map(lambda bins: bins.mid, list(gby_tip.keys())))
    gby_tips = gby_tip.values()

    tip_gby_total_bill_bins = dict(zip(mid_total_bill_bins, gby_tips))
  4. 通过传递给箱线图的每个矩形来创建图表每个相应箱子的质心

    fig, ax1 = plt.subplots(dpi=200)
    ax2 = ax1.twinx()

    bp_values = list(tip_gby_total_bill_bins.values())
    bp_pos = list(tip_gby_total_bill_bins.keys())

    l1 = sns.histplot(tips.total_bill, bins=10, ax=ax1)
    l2 = ax2.boxplot(bp_values, positions=bp_pos, manage_ticks=False, patch_artist=True, widths=2)

    #Average tips as hline
    avg_tip = np.mean(tips.tip)
    ax2.axhline(y=avg_tip, color='red', linestyle="--", label="avg tip")
    ax2.set_yticks(list(ax2.get_yticks() + avg_tip)) #add value of avg(tip) to y-axis

    #Average total_bill as vline
    avg_total_bill=np.mean(tips.total_bill)
    ax1.axvline(x=avg_total_bill, color='orange', linestyle="--", label="avg tot_bill")

然后是结果。

Tips ~ Total_bill distribution

关于pandas - 在直方图的相对 bin 上叠加箱线图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70598044/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com