Reputation: 49
I managed to find and customize some matplotlib code to create grouped bar charts. However, the code doesn't have labels at the top. I have tried several approaches, but I'm just not getting it right.
My end goal will be:
Any help (especially with #1) is greatly appreciated!
The code:
#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")
Upvotes: 1
Views: 9564
Reputation: 339220
The solution is similar to the one in this question: Adding value labels on a matplotlib bar chart
However I provide you with an example which uses your own type of plot, and thus makes it easier to understand.
The general idea in order to obtain labels on top of bars, is to iterate over the patches within the axes and annotate them with their respecticve heights.
I simplified the code a bit.
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()
Upvotes: 3