将数据标签添加到MatPlotLib中的分组条形图

Add data label to grouped bar chart in MatPlotLib

我设法找到并自定义了一些matplotlib代码以创建分组的条形图。但是,该代码的顶部没有标签。我已经尝试了几种方法,但是我只是做得不好。

我的最终目标将是:

  • 在每个栏的顶部添加数据标签
  • 摆脱外部和y轴标签周围的黑色边框
  • 任何帮助(尤其是#1帮助)都将不胜感激!

    代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    #Code adapted from:  
    #https://chrisalbon.com/python/matplotlib_grouped_bar_plot.html
    #matplotlib online

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


    raw_data = {'plan_type': ['A1', 'A2', 'A3', 'A4', 'A5', 'A6'],
            'Group A':     [100, 0, 0, 0, 0, 0],
            'Group B':     [48, 16, 9, 22, 5, 0],
            'Group C':     [18, 28, 84, 34, 11, 0],
            'Group D': [49, 13, 7, 23, 6, 0],
            'Group E':          [57, 16, 9, 26, 3, 0]

        }
    df = pd.DataFrame(raw_data, columns = ['plan_type', 'Group B', 'Group C', 'Group D', 'Group E'])


    df2 =pd.DataFrame(raw_data, columns = ['plan_type', 'Group A'])



    # Setting the positions and width for the bars
    pos = list(range(len(df['Group B'])))
    width = 0.2

    # Plotting the bars
    fig, ax = plt.subplots(figsize=(7, 2))


    #This creates another y-axis that shares the same x-axis


    # Create a bar with Group A data,
    # in position pos + some width buffer,
    plt.bar(pos,
        #using df['Group E'] data,
        df2['Group A'],
        # of width
        width*8,
        # with alpha 0.5
        alpha=1,
        # with color
        color='#E6E9ED',
        # with label the fourth value in plan_type
        label=df2['plan_type'][0])


    # Create a bar with Group B data,
    # in position pos,
    plt.bar(pos,
        #using df['Group B'] data,
        df['Group B'],
        # of width
        width,
        # with alpha 1  
        alpha=1,
        # with color
        color='#900C3F',
        # with label the first value in plan_type
        label=df['plan_type'][0])

    # Create a bar with Group C data,
    # in position pos + some width buffer,
    plt.bar([p + width for p in pos],
        #using df['Group C'] data,
        df['Group C'],
        # of width
        width,
        # with alpha 1
        alpha=1.0,
        # with color
        color='#C70039',
        # with label the second value in plan_type
        label=df['plan_type'][1])

    # Create a bar with Group D data,
    # in position pos + some width buffer,
    plt.bar([p + width*2 for p in pos],
        #using df['Group D'] data,
        df['Group D'],
        # of width
        width,
        # with alpha 1
        alpha=1,
        # with color
        color='#FF5733',
        # with label the third value in plan_type
        label=df['plan_type'][2])

    # Create a bar with Group E data,
    # in position pos + some width buffer,
    plt.bar([p + width*3 for p in pos],
        #using df['Group E'] data,
        df['Group E'],
        # of width
        width,
        # with alpha 1
        alpha=1,
        # with color
        color='#FFC300',
        # with label the fourth value in plan_type
        label=df['plan_type'][3])


    # Set the y axis label
    ax.set_ylabel('Percent')

    # Set the chart's title
    ax.set_title('A GRAPH - YAY!', fontweight ="bold")

    # Set the position of the x ticks
    ax.set_xticks([p + 1.5 * width for p in pos])

    # Set the labels for the x ticks
    ax.set_xticklabels(df['plan_type'])

    # Setting the x-axis and y-axis limits
    plt.xlim(min(pos)-width, max(pos)+width*5)
    plt.ylim([0, 100] )
    #plt.ylim([0, max(df['Group B'] + df['Group C'] + df['Group D'] + df['Group E'])] )

    # Adding the legend and showing the plot.  Upper center location, 5 columns,
    Expanded to fit on one line.
    plt.legend(['Group A','Group B', 'Group C', 'Group D', 'Group E'], loc='upper center', ncol=5, mode='expand', fontsize  ='x-small')

    #plt.grid()  --> This would add a Grid, but I don't want that.

    plt.show()
    plt.savefig("PlanOffered.jpg")

    解决方案与此问题中的解决方案类似:
    在matplotlib条形图上添加值标签

    但是,我为您提供了一个示例,该示例使用了您自己的绘图类型,因此更易于理解。

    为了在条形图的顶部获得标签,通常的想法是遍历轴内的斑块,并用其相应的高度标注它们。

    enter image description here

    我简化了代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np

    raw_data = {'plan_type': ['A1', 'A2', 'A3', 'A4', 'A5', 'A6'],
            'Group A':     [100, 0, 0, 0, 0, 0],
            'Group B':     [48, 16, 9, 22, 5, 0],
            'Group C':     [18, 28, 84, 34, 11, 0],
            'Group D': [49, 13, 7, 23, 6, 0],
            'Group E':          [57, 16, 9, 26, 3, 0]

        }
    df2 =pd.DataFrame(raw_data, columns = ['plan_type', 'Group A'])
    df = pd.DataFrame(raw_data,
                      columns = ['plan_type', 'Group B', 'Group C', 'Group D', 'Group E'])

    ax = df2.plot.bar(rot=0,color='#E6E9ED',width=1)
    ax = df.plot.bar(rot=0, ax=ax, color=["#900C3F", '#C70039', '#FF5733', '#FFC300'],
                     width = 0.8 )

    for p in ax.patches[1:]:
        h = p.get_height()
        x = p.get_x()+p.get_width()/2.
        if h != 0:
            ax.annotate("%g" % p.get_height(), xy=(x,h), xytext=(0,4), rotation=90,
                       textcoords="offset points", ha="center", va="bottom")

    ax.set_xlim(-0.5, None)
    ax.margins(y=0)
    ax.legend(ncol=len(df.columns), loc="lower left", bbox_to_anchor=(0,1.02,1,0.08),
              borderaxespad=0, mode="expand")
    ax.set_xticklabels(df["plan_type"])
    plt.show()