简体   繁体   中英

How to plot and annotate a grouped bar chart

I came across a tricky issue about the matplotlib in Python. I want to create a grouped bar chart with several codes, but the chart goes wrong. Could you please offer me some advice? The code is as follows.

import numpy as np
import pandas as pd
file="https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/DV0101EN/labs/coursera/Topic_Survey_Assignment.csv"
df=pd.read_csv(file,index_col=0)

df.sort_values(by=['Very interested'], axis=0,ascending=False,inplace=True)

df['Very interested']=df['Very interested']/2233
df['Somewhat interested']=df['Somewhat interested']/2233
df['Not interested']=df['Not interested']/2233
df

df_chart=df.round(2)
df_chart

labels=['Data Analysis/Statistics','Machine Learning','Data Visualization',
       'Big Data (Spark/Hadoop)','Deep Learning','Data Journalism']
very_interested=df_chart['Very interested']
somewhat_interested=df_chart['Somewhat interested']
not_interested=df_chart['Not interested']

x=np.arange(len(labels))
w=0.8

fig,ax=plt.subplots(figsize=(20,8))
rects1=ax.bar(x-w,very_interested,w,label='Very interested',color='#5cb85c')
rects2=ax.bar(x,somewhat_interested,w,label='Somewhat interested',color='#5bc0de')
rects3=ax.bar(x+w,not_interested,w,label='Not interested',color='#d9534f')

ax.set_ylabel('Percentage',fontsize=14)
ax.set_title("The percentage of the respondents' interest in the different data science Area",
            fontsize=16)
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend(fontsize=14)

def autolabel(rects):
    """Attach a text label above each bar in *rects*, displaying its height."""
    for rect in rects:
        height = rect.get_height()
        ax.annotate('{}'.format(height),
                    xy=(rect.get_x() + rect.get_width() / 3, height),
                    xytext=(0, 3),  # 3 points vertical offset
                    textcoords="offset points",
                    ha='center', va='bottom')


autolabel(rects1)
autolabel(rects2)
autolabel(rects3)

fig.tight_layout()

plt.show()

The output of this code module is really a mess. But what I expect should look like the bar chart in the picture. Could you please tell me which point is not correct in my codes?

在此处输入图像描述

Imports and DataFrame

import pandas as pd
import matplotlib.pyplot as plt

# given the following code to create the dataframe
file="https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/DV0101EN/labs/coursera/Topic_Survey_Assignment.csv"
df=pd.read_csv(file, index_col=0)

df.sort_values(by=['Very interested'], axis=0, ascending=False, inplace=True)

# all columns are being divided by 2233 so those lines can be replace with the following single line
df = df.div(2233)

# display(df)
                            Very interested  Somewhat interested  Not interested
Data Analysis / Statistics         0.755934             0.198836        0.026870
Machine Learning                   0.729512             0.213614        0.033139
Data Visualization                 0.600090             0.328706        0.045678
Big Data (Spark / Hadoop)          0.596507             0.326467        0.056874
Deep Learning                      0.565607             0.344828        0.060905
Data Journalism                    0.192118             0.484102        0.273175

Using since matplotlib v3.4.2

# your colors
colors = ['#5cb85c', '#5bc0de', '#d9534f']

# plot with annotations is probably easier
p1 = df.plot(kind='bar', color=colors, figsize=(20, 8), rot=0, ylabel='Percentage', title="The percentage of the respondents' interest in the different data science Area")

for p in p1.containers:
    p1.bar_label(p, fmt='%.2f', label_type='edge')

在此处输入图像描述

Annotation Resources - from matplotlib v3.4.2

Using before matplotlib v3.4.2

  • w = 0.8 / 3 will resolve the issue, given the current code.
  • However, generating the plot can be accomplished more easily with pandas.DataFrame.plot
# your colors
colors = ['#5cb85c', '#5bc0de', '#d9534f']

# plot with annotations is probably easier
p1 = df.plot.bar(color=colors, figsize=(20, 8), ylabel='Percentage', title="The percentage of the respondents' interest in the different data science Area")
p1.set_xticklabels(p1.get_xticklabels(), rotation=0)

for p in p1.patches:
    p1.annotate(f'{p.get_height():0.2f}', (p.get_x() + p.get_width() / 2., p.get_height()), ha = 'center', va = 'center', xytext = (0, 10), textcoords = 'offset points')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM