Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
25
Help us understand the problem. What is going on with this article?
@s_fukuzawa

Pythonのmatplotlibで積み上げ棒グラフを作成しデータラベルを追加してみた

More than 1 year has passed since last update.

matplotlibで積み上げ棒グラフを描いてみる

モチベーション

積み上げ棒グラフをPythonで描く際に、エクセルみたいにデータラベルを表示できたらいいなぁと思い、いざ調べてみるとデータラベルを表示できるような記事が無く、コピペできるコードもありませんでした。そこで、積み上げ棒グラフにデータラベルをつけようと思った時にコピペできるコードを書いてみました。

ちなみに、積み上げ棒グラフだけ描ければいいのであれば、このページの一番最後にある簡単に積み上げ棒グラフを描くを参考にしてください。

インポート

以下のライブラリーをインポートします。


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

sns.set(font='IPAexGothic')

%matplotlib inline

ダミーデータの作成

ダミーデータはA,B,C支店の月別の売り上げデータを作成しました。


dataset = pd.DataFrame([[100, 200, 50], [300, 400, 600], [50, 300, 60]], 
                       columns=['A支店', 'B支店', 'C支店'], 
                       index=['4月', '5月', '6月'])
A支店 B支店 C支店
4月 100 200 50
5月 300 400 600
6月 50 300 60

棒グラフを描く

まずは簡単な棒グラフを描いてみます。
各支店の月の売り上げを合計した棒グラフを描いてみましょう。
描いてみたは良いもののこれだけだと、各月にどれくらい売り上げがあるのかわかりません。。。
そんな時は、積み上げ棒グラフを使いましょう!

fig, ax = plt.subplots(figsize=(10, 8))
ax.bar(dataset.columns, dataset.sum())
plt.show()

image.png

積み上げ棒グラフを描く

積み上げ棒グラフは棒グラフを描く時と同様にax.bar()を使います。
この時の引数bottomにバーのベースとなるy座標を指定します。
積み上げ棒グラフができました!!!やはり、データラベルが欲しいですね。
参考サイト:https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.bar.html


fig, ax = plt.subplots(figsize=(10, 8))
for i in range(len(dataset)):
    ax.bar(dataset.columns, dataset.iloc[i], bottom=dataset.iloc[:i].sum())
ax.set(xlabel='支店名', ylabel='売り上げ')
ax.legend(dataset.index)
plt.show()

image.png

積み上げ棒グラフ内にデータラベルを表示する

いよいよここからが本題です。
データラベルは、plt.text()でx座標とy座標を指定して挿入します。
そうすると、いい感じにできました!


fig, ax = plt.subplots(figsize=(10, 8))
for i in range(len(dataset)):
    ax.bar(dataset.columns, dataset.iloc[i], bottom=dataset.iloc[:i].sum())
    for j in range(len(dataset.columns)):
        plt.text(x=j, 
                 y=dataset.iloc[:i, j].sum() + (dataset.iloc[i, j] / 2), 
                 s=dataset.iloc[i, j], 
                 ha='center', 
                 va='bottom'
                )
ax.set(xlabel='支店名', ylabel='売り上げ')
ax.legend(dataset.index)
plt.show()

image.png

100%積み上げ棒グラフを描く

積み上げ棒グラフを使う時には100%積み上げ棒グラフも使用したくなりますよね。
まずはデータを加工します。
以下のコードで支店別の売り上げを割合に変換します。


plot_dataset = pd.DataFrame(index = dataset.index)
for col in dataset.columns:
    plot_dataset[col] = round(100 * dataset[col] / dataset[col].sum(), 1)
A支店 B支店 C支店
4月 22.2 22.2 7.0
5月 66.7 444. 84.5
6月 11.1 33.3 8.5

変換したデータを使って100%積み上げ棒グラフを描きましょう。
コードは先ほどのコードを同じです。(変数だけ変更しています。)


fig, ax = plt.subplots(figsize=(10, 8))
for i in range(len(plot_dataset)):
    ax.bar(plot_dataset.columns, 
           plot_dataset.iloc[i], 
           bottom=plot_dataset.iloc[:i].sum()
          )
    for j in range(len(plot_dataset.columns)):
        plt.text(x=j, 
                 y=plot_dataset.iloc[:i, j].sum()+(plot_dataset.iloc[i, j]/2), 
                 s=f'{plot_dataset.iloc[i, j]}%', 
                 ha='center', 
                 va='bottom'
                )
ax.set(xlabel='支店名', ylabel='売り上げ')
ax.legend(plot_dataset.index)
plt.show()

image.png

簡単に積み上げ棒グラフを描く

積み上げ棒グラフを描くだけなら以下のコードで簡単に描けます。

fig, ax = plt.subplots(figsize=(10, 8))
dataset.T.plot(kind='bar', stacked=True, ax=ax)
plt.show()

image.png

25
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
s_fukuzawa
データ分析しています。 著書:直感でわかる! Excelで機械学習
datamix
データサイエンスに関わる最適なサービスを継続的に提供することで、企業・地域・社会に属するひとりひとりが、客観的に意思決定する力を高め、自由に、そして平等に活躍できる世界を実現します。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
25
Help us understand the problem. What is going on with this article?