【问题标题】:How to plot and annotate grouped bars in seaborn / matplotlib如何在 seaborn / matplotlib 中绘制和注释分组条形
【发布时间】:2020-11-23 00:09:47
【问题描述】:

我有一个如下所示的数据框:

我使用条形图来表示每一行的订阅者。这就是我所做的:

data = channels.sort_values('subscribers', ascending=False).head(5)
chart = sns.barplot(x = 'name', y='subscribers',data=data)
chart.set_xticklabels(chart.get_xticklabels(), rotation=90)
for p in chart.patches:
    chart.annotate("{:,.2f}".format(p.get_height(), '.2f'), (p.get_x() + p.get_width() / 2., p.get_height()), ha = 'center', va = 'center', xytext = (0, 10), textcoords = 'offset points')

现在我想在同一个图上显示每个用户的“video_count”。目标是比较订阅者数量与视频数量的关系。如何在图表上描述这一点?

【问题讨论】:

    标签: python pandas matplotlib seaborn bar-chart


    【解决方案1】:

    数据

    • 数据需要使用.melt转换成长格式
    • 由于值的比例,'log' 用于yscale
    • 'cats' 中的所有类别都包含在示例中。
      • 熔解前只选择所需的列,或使用dfl = dfl[dfl.cats.isin(['sub', 'vc']) 过滤所需的'cats'
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    # setup dataframe
    data = {'vc': [76, 47, 140, 106, 246],
            'tv': [29645400, 28770702, 50234486, 30704017, 272551386],
            'sub': [66100, 15900, 44500, 37000, 76700],
            'name': ['a', 'b', 'c', 'd', 'e']}
    df = pd.DataFrame(data)
    
        vc        tv    sub name
    0   76  29645400  66100    a
    1   47  28770702  15900    b
    2  140  50234486  44500    c
    
    # convert to long form
    dfl = (df.melt(id_vars='name', var_name='cats', value_name='values')
           .sort_values('values', ascending=False).reset_index(drop=True))
    
      name cats     values
    0    e   tv  272551386
    1    c   tv   50234486
    2    d   tv   30704017
    

    更新至matplotlib v3.4.2

    # plot
    fig, ax = plt.subplots(figsize=(12, 6))
    sns.barplot(x='name', y='values', data=dfl, hue='cats', ax=ax)
    ax.set_xticklabels(ax.get_xticklabels(), rotation=0)
    ax.set_yscale('log')
    
    for c in ax.containers:
        # set the bar label
        ax.bar_label(c, fmt='%.0f', label_type='edge', padding=1)
        
    # pad the spacing between the number and the edge of the figure
    ax.margins(y=0.1)
    

    注释资源 - 来自matplotlib v3.4.2

    使用seaborn v0.11.1 绘图

    • 在版本 3.4.2 之前使用 matplotlib
    • 请注意,使用 .annotate.patches 比使用 .bar_label 更冗长。
    # plot
    fig, ax = plt.subplots(figsize=(12, 6))
    sns.barplot(x='name', y='values', data=dfl, hue='cats', ax=ax)
    ax.set_xticklabels(chart.get_xticklabels(), rotation=0)
    ax.set_yscale('log')
    
    for p in ax.patches:
        ax.annotate(f"{p.get_height():.0f}", (p.get_x() + p.get_width() / 2., p.get_height()),
                    ha='center', va='center', xytext =(0, 7), textcoords='offset points')
    

    【讨论】:

      猜你喜欢
      • 2020-12-09
      • 2022-01-11
      • 1970-01-01
      • 2020-03-22
      • 1970-01-01
      • 2020-04-22
      • 2019-03-10
      • 2023-03-16
      • 2016-06-12
      相关资源
      最近更新 更多