YutaKaのPython教室

Python の文法やライブラリ、API、環境構築について画像・動画・ソースコード付きで徹底解説!

Matplotlib 棒グラフの描き方|複数系列・積み上げ棒グラフも全てOK

Matplotlibを使えば、様々な棒グラフを描くことができます。

とはいっても、実際に使ってみると次のような問題に直面することも…。

  • Matplotlibで棒グラフを作成する方法がよくわからない…。
  • 棒グラフで悩むなら、MatplotlibあきらめてExcel使おうかな…。

そこで、今回は棒グラフについて、次の内容をわかりやすく解説しました。

  • Matplotlibで棒グラフを描く基本的な方法
  • 棒グラフ要素の見た目変更方法
  • 積み上げ棒グラフ、複数系列の棒グラフ作成方法

このあたりを網羅すると、Matplotlibでサラッと棒グラフを作れるようになってきます!

Matplotlibで棒グラフ作成するときの超基本

Matplotlibで棒グラフを作成する際には、主に2つの方式があります。

  • pltメソッドの場合:plt.bar()
  • オブジェクト指向の場合:ax.bar()

pltメソッドとオブジェクト指向は次のように分類しています。

  • pltメソッド:plt.○○○を使用して、グラフを作成していく方法
  • オブジェクト指向:fig, ax = plt.subplots()から始めて、ax.○○○を使用していく方法

この解説は基本的にplt.bar()で解説しますが、ax.bar()でも挙動はほぼ同じです。

オブジェクト指向の方はax.bar()で実行してください。

pltメソッドでのグラフ描画について、よくわからない方は次のMatplotlib入門記事も参考にしてください。

≫【初心者向け】Matplotlibの特徴と使い方をわかりやすく解説!
脱初心者のためのMatplotlibマスターガイドです。そもそもどういう流れでプロットするのか?どんな種類のグラフが描けるのか?日本語設定は?タイトルや軸の設定は?オブジェクト指向って何?そんな疑問を解決します!この記事で、脱Matplotlib初心者を目指そう!
www.yutaka-note.com/entry/matplotlib_guid
 

また、fig, ax = plt.subplots()で始まるオブジェクト指向プロットは、次の記事で解説しています。

≫Matplotlib plt.subplots()の使い方|FigureとAxesを同時生成!
Matplotlibでグラフを描くとき「fig, ax = plt.subplots()って、よく見るけど何してるの?」「plt.subplots()の便利な使い方を知りたい! 」という方のために、plt.subplots()でFigureとAxesを作ると何が便利なのか、plt.subplots()の基本的な使い方、覚えておくと便利なplt.subplots()の引数をを図解付きで解説します!
www.yutaka-note.com/entry/matplotlib_subplots
 

基本的な棒グラフの作成|plt.bar()

超基本的な棒グラフの作成の流れは、次の通りです。

  • plt.bar(x, heigh)でプロットを生成
  • plt.show()でプロットを表示(Notebookの場合は省略可能)

plt.bar()の必須の引数は次の通りです。

内容 引数
各棒の位置 x=[array_like] リストndarrayなど
各棒の高さ height=[array_like] リストndarrayなど

pltメソッドとオブジェクト指向でそれぞれ、基本的な棒グラフを描いてみます。

まずMatplotlibをインポートして、サンプルグラフ用のデータを用意します。

import matplotlib.pyplot as plt
import numpy as np 
 
x = [1, 2, 3, 4]
height = [10, 20, 30, 40]

pltメソッドとオブジェクト指向でそれぞれ棒グラフを描きます。

plt.bar(x, height)
plt.show()
fig, ax = plt.subplots()
 
ax.bar(x, height)
plt.show()

pltメソッドでもオブジェクト指向でも同じグラフが出力されます。

xで指定した位置に、heightの高さの四角形が配置されて棒グラフになっていますね。

plt.bar()は本質的には、四角形を棒グラフになるように配置してくれる機能です。

そう考えると、棒(四角)の位置をxで、棒の高さをheightで設定するのも理解できますね。

ラベル名に文字列を設定|tick_label

棒グラフを作成する場合は、横軸にラベル名を設定したい場合がほとんどだと思います。

横軸にラベル名を設定するには、まず[ラベル名のリスト]を用意します(実際には、リストでなくてもarray_likeならOK)。

  • labels = ["ラベル名1", "ラベル名2","ラベル名3",…]

その後、次のどちらかの方法で設定します。

  1. 棒グラフ作成時に引数で指定|plt.bar(x, height, tick_label=labels)
  2. 棒グラフ作成後にラベルを更新|plt.xticks(x, labels)

1. 棒グラフ作成時に引数で指定|plt.bar(x, height, tick_label=labels)の例

x = [1, 2, 3, 4]
height = [10, 20, 30, 40]
labels = ["Apple", "Banana", "Carrot", "Daikon"]
 
plt.bar(x, height, tick_label=labels)

2. 棒グラフ作成後にラベルを更新|plt.xticks(x, labels)の例

x = [1, 2, 3, 4]
height = [10, 20, 30, 40]
labels = ["Apple", "Banana", "Carrot", "Daikon"]
 
plt.bar(x, height)
plt.xticks(x, labels)

どちらのコードでも、横軸にラベルが設定されます。

特に使い分けはないと思いますが、私の場合はひとつのグラフ内で複数回plt.bar()を使用する場合には、plt.xtiks()を使用しています。
(複数系列のグラフや積み上げグラフを作成する場合です)

plt.bar(x, height, tick_label=labels)だと同じラベルを繰り返し設定することになり、違和感があるからです。

plt.xticks()などの軸周りの設定に関しては、次の記事でまとめています。

≫Matplotlib 軸周り完璧マスターガイド | 軸・軸目盛・目盛り線の設定
Matplotlibで大変なのが軸周りの設定!グラフの「この要素」を変更するには、「どのメソッド」を使えばいいのかわからない…。という方のために、Matplotlibの軸・目盛り・目盛り線の設定について総まとめしました!これで軸周りの設定がだいぶ楽になります。軸周り完ぺきマスターガイド!
www.yutaka-note.com/entry/matplotlib_axis
 

オブジェクト指向の場合、xticks()でのラベル名変更方法が異なりますので注意してください(詳しくは上の記事で)。

また、ラベル名に日本語を使用したい場合には特別な設定が必要になります。次の記事を参考にしてください。

≫Matplotlib 日本語の表示方法 厳選3選|最適な方法選んで!
Matplotlibでグラフを描くとき、「日本語を表示しようとしたら文字化けした!」「日本語を表示するには、何を設定すればいいの?」という方向けに、「Matplotlibで日本語を表示する方法厳選3選」、「使用できるフォントのチェック方法」を紹介していきます。追加のインストールなしで、フォントの設定を変更するだけの方法を紹介します!
www.yutaka-note.com/entry/matplotlib_japanese
 

棒の枠線の見た目変更

棒の枠線の見た目は、plt.bar()のキーワード引数で変更することができます。

キーワード 略称 設定内容 設定値の例
edgecolor ec 枠線の色 色の名前など ex) gray, red, blue
linewidth lw 線の太さ 数値ptで指定
linestyle ls 線のスタイル -, --, -., :, で指定

枠線の色|edgecolor

edgecolor"色名"または["色名"などのリスト]を渡します。

  • "色名"などの文字列単体:グラフ全体に適用
  • ["色名"などのリスト]:各棒の枠線に適用

まずは、文字列単体を与えてグラフ全体に適用する例を確認してみます。

plt.bar(x, height, edgecolor="lime") 

次のように全ての棒の枠線がライム色の棒グラフが出力されます。

続いて、色名をリストで与えて、各棒の枠線を個別に設定する例を見てみます。

colors = ["black", "red", "blue", "green"]
 
plt.bar(x, height, edgecolor = colors, linewidth = 5) 

次のように各棒の枠線の色が個別に設定されています。

色の設定について詳しく知りたい方はこちらをチェックしてください。

≫Matplotlib color 色の指定 | 一文字指定からカラーマップの使い方まで徹底解説
伝わるグラフを作るためのポイントはなんでしょうか?いかに視覚的にわかりやすいか、これが大切です。それには重要な要素に色をつけて、視覚的にうったえることが超大切!この記事では、matplotlibでの色の指定方法について、基本から応用まで徹底解説!
www.yutaka-note.com/entry/matplotlib_color
 

枠線の太さ|linewidth

edgewidthに太さを、数値ptまたは[数値ptのリスト]で渡します。

  • 数値pt:グラフ全体に適用
  • 数値ptのリスト:各棒の枠線に適用

まずは、数値単体を与えてグラフ全体に適用する例を確認してみます。

plt.bar(x, height, edgecolor="black", linewidth=5)

次のように全ての棒の枠線の太さが変更されます。

続いて数値をリストで与えて、各棒の枠線を個別に設定する例を見てみます。

linewidths = [1, 2, 3, 4]
 
plt.bar(x, height, edgecolor="black", linewidth=linewidths) 

次のように各棒の枠線の太さが個別に設定されています。

枠線のスタイル|linestyle

枠線のスタイルを変更する場合は、linestyleで指定します。

  • linestyle = "スタイルを指定する文字列"

使用できるスタイルは次の表のとおりです。

線の種類
'-' 実線
'--' 破線
'-.' 一点鎖線
':' 点線

破線を適用した例を紹介します。

plt.bar(x, height, edgecolor="black", linewidth=5, linestyle="—") 

棒の見た目変更

棒の見た目は、plt.bar()のキーワード引数で変更することができます。

キーワード 設定内容 設定値の例
width 棒の太さ 数値ptで指定
facecolor
別称:fc, color
棒の色 色の名前など ex) gray, red, blue
alpha 棒の透明度 0(完全透明)~(不透明)
hatch 棒の柄 '/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*'で指定

棒の太さ|width

widthに太さを、数値ptで渡します。

  • width = 数値(デフォルト:0.8pt)

widthの値をx(各棒の位置)の間隔と同じにすると、棒を隙間なく配置できます。

x = [1, 2, 3, 4]
height = [10, 20, 30, 40]
 
plt.bar(x, height, width=1)

棒の隙間がないと見にくいので、枠線も同時に設定するのがおススメです。

plt.bar(x, height, width=1, edgecolor="black", linewidth=2)

棒の色|color

facecolor"色名"または["色名"などのリスト]を渡します。

  • 色名などの文字列単体:グラフ全体に適用
  • 色名などのリスト:各棒の枠線に適用

facecolorの代わりにcolor, fcを使用することも可能です。

まずは、文字列単体を与えてグラフ全体に適用する例を確認してみます。

plt.bar(x, height, facecolor = "lightblue") 

次のように全ての棒が水色になります。

続いて、色名をリストで与えて、各棒の色を個別に設定する例を見てみます。

colors = ["black", "red", "blue", "green"]
 
plt.bar(x, height, color = colors) 

次のように各棒の色が個別に設定されています。

全体の色を変更する応用例として、棒の高さに応じて色を濃くする方法を紹介します。

この場合には、Matplotlibのカラーマップを使用します。

x = np.array([1, 2, 3, 4])
height = np.array([10, 20, 100, 30])
 
#カラーマップの生成
cm = plt.get_cmap("Wistia") 
norm_height = (height - height.min()) / (height.max() - height.min()) # 高さを0~1に正規化
color = cm(norm_height) # 棒の高さに応じた色を生成
 
plt.bar(x, height, color = color)

棒の高さに応じて色が設定されています。

カラーマップは、Matplotlibに組み込まれた色のセットです。

カラーマップを含めた色の詳細については、次の記事でまとめています。

≫Matplotlib color 色の指定 | 一文字指定からカラーマップの使い方まで徹底解説
伝わるグラフを作るためのポイントはなんでしょうか?いかに視覚的にわかりやすいか、これが大切です。それには重要な要素に色をつけて、視覚的にうったえることが超大切!この記事では、matplotlibでの色の指定方法について、基本から応用まで徹底解説!
www.yutaka-note.com/entry/matplotlib_color
 

棒の透明度|alpha

alpha0から1の数値で透明度を与えることができます。

  • 0:完全透明
  • 1:不透明

alpha = 0.5にして、半透明にしてみます。

plt.bar(x, height, alpha=0.5) 

棒の柄(テクスチャ)|hatch

hatchに、'/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*'を設定します。

'/'を適用した例を紹介します。

plt.bar(x, height, hatch="/", color = "skyblue")

'//'のように同じ記号を繰り返すと、柄の密度を上げることができます。

x = [0, 1]
height = np.array([10]*2) # => [10, 10]のndarray
 
plt.bar(x, height, hatch="/")
plt.bar(x, height, hatch="//", bottom=height)
plt.bar(x, height, hatch="/"*3, bottom=height*2)

文字列の繰り返しなので、"/"*3 = "///"という文字列の演算子を活用すると便利ですね。

棒の柄を個別適用するためには、オブジェクト指向でプロットします。

全ての柄を表示しているので、柄選定の参考にしてください。

hatch_list = 	('/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*')
 
x = np.arange(len(hatch_list))
height = 10
 
fig, ax =plt.subplots()
 
# 棒オブジェクト達をbars受け取る
bars = ax.bar(x, height, tick_label=hatch_list, color = "skyblue")
 
# 各棒を取り出して、bar.set_hatch()で柄を適用
for bar, hatch in zip(bars, hatch_list):
    bar.set_hatch(hatch)

棒の見た目変更をもっと詳しく!

前述の通り、Matplotlibでは、四角の図形を適切に配置することで、棒グラフにしています。

そのため、図形の見た目設定をよく理解すれば、棒グラフの設定をより細かく行うことができます。

図形の設定ついては、次の記事を参考にしてください。

≫Matplotlib 図形を描く方法|円や四角形の描き方をわかりやすく解説
Matplotlibには、円や四角形など様々な図形を描画する機能が備わっていますが、初めのうちは使い方がわかりにくです…。そこで、「Matplotlibでグラフ内に図形を描くにはどうしたらいいの?」という方のために、Matplotlibで円や四角形、矢印などの図形を描く方法、図形の見た目を自分好みにアレンジする方法について紹介します。
www.yutaka-note.com/entry/matplotlib_patches
 

積み上げ棒グラフの作成方法

積み上げ棒グラフを作成するには、次の手順を踏みます。

  • 1系列目の棒グラフをプロット
  • 1系列目の棒の高さ分だけy方向にずらして、2系列目の棒グラフをプロット

キーワード引数bottomで2系列目を配置する高さをずらします。

x = [1, 2, 3, 4]
height = [10, 20, 30, 40]
height2 =[5, 10, 15, 20]
 
plt.bar(x, height)
plt.bar(x, height2, bottom=height)

3系列以上ある場合には、同様に1+2系列目分だけ高さをずらせばOKです。

DataFrameの積み上げテンプレート

DataFrameから積み上げ棒グラフを作成する場合のテンプレートの例を紹介します。

次のサンプルDataFrameを使用してみます。

import pandas as pd
data = {"Apple":[1, 2, 3, 4],
        "Banana":[0, 1, 2, 3],
        "Carrot":[0, 0, 1, 2]}
 
df = pd.DataFrame(data, pd.Index(["2020", "2021", "2022", "2023"], name="Year"))
#       Apple  Banana  Carrot
# Year                       
# 2020      1       0       0
# 2021      2       1       0
# 2022      3       2       1
# 2023      4       3       2

次のように、for文の中でbottomを適宜更新するようにすると、簡単に積み上げ棒グラフが作れます。

bottom = np.zeros_like(df.index)
for name in df.columns:
    plt.bar(df.index, df[name], bottom=bottom, label=name)
    bottom += df[name]
    
plt.legend()

  • 【参考】凡例の設定については、次の記事を参考にしてください。
≫Matplotlib plt.legend() | 凡例の位置とスタイル設定完璧ガイド!
Matplotlibでは、デフォルトでは凡例は表示されません。「凡例(legend)を表示するにはどうしたらいいの?!」「凡例の位置や見た目の設定方法がわからない!」という方向けに、「凡例を表示する関数plt.legend()の使い方」「引数で位置や見た目を簡単に設定する方法」を紹介していきます。自分の作りたい凡例を作れるようになりましょう!
www.yutaka-note.com/entry/matplotlib_legend
 

複数系列の棒グラフの作成方法

棒の配置align、太さwidthを変更して、複数系列の棒グラフを作成できます。

少しややこしい部分があるので、次の順番で一歩ずつ解説していきます。

  • 棒の配置の変更|align
  • 2系列のグラフ作成|widthalignの組み合わせ
  • 複数系列のグラフテンプレート

棒の配置変更|align

キーワード引数alignで、の値のどの位置に棒を配置するかを調整できます。

キーワード 設定内容
Align 'center'(デフォルト) 棒の中心がxに位置するように配置
  'edge' 棒の左端がxに位置するように配置

次のグラフで、'center'(デフォルト)edge'を比較します。

x = [1, 2, 3, 4]
height = [10, 20, 30, 40]
height2 =[5, 10, 15, 20]
 
plt.bar(x, height)
plt.bar(x, height2, align="edge")

1系列目と2系列目で、xに対する棒の位置がずれていますね。

複数系列棒グラフ(2系列簡易ver.)

2系列の棒グラフを作成する場合は、次のように設定します。

  • align = 'edge'
  • width(一系列目)= 負の値
  • width(二系列目)= 正の値

すると、棒がxの左右に配置されるので、二系列棒グラフを手軽に作成できます。

x = [1, 2, 3, 4]
height = [10, 20, 30, 40]
height2 =[5, 10, 15, 20]
 
plt.bar(x, height, align="edge", width=-0.3)
plt.bar(x, height2, align="edge", width= 0.3)

この方法は直感的なので、簡単に記憶できますね。

ただし、3系列以上では対応できないので、任意の系列数に対応できるテンプレートも紹介します。

複数系列棒グラフのテンプレート(任意の系列数)

3系列以上でも対応できる複数系列棒グラフのテンプレートを紹介します。

系列数に応じて、次の2つの引数を調整するところがポイントです。

  • 各棒の配置位置|pos = x - totoal_width *( 1- (2*i+1)/len(data) )/2
  • 棒の幅|width = totoal_width/len(data)

テンプレート化すると次のようになります。

# 棒の配置位置、ラベルを用意
x = np.array([1, 2, 3, 4])
labels = ["Apple", "Banana", "Carrot", "Daikon"]
 
# 各系列のデータを用意
height = np.random.rand(4)
height2 = np.random.rand(4)
height3 = np.random.rand(4)
height4 = np.random.rand(4)
data = [height, height2,height3,height4]
 
# マージンを設定
margin = 0.2  #0 <margin< 1
totoal_width = 1 - margin
 
# 棒グラフをプロット
for i, h in enumerate(data):
  pos = x - totoal_width *( 1- (2*i+1)/len(data) )/2
  plt.bar(pos, h, width = totoal_width/len(data))
 
# ラベルの設定
plt.xticks(x, labels)

今回はベタ打ちですが、関数化して使っても便利ですね!

系列毎の色の変更方法

複数系列の場合、デフォルトでは系列毎に青→オレンジ→…と色が自動で変化していきます。

この色のサイクル(カラーサイクル)を変更したい場合は、カラーマップを使用すると便利です。

例えば、次のように淡い色合いに変えることも簡単です。

実はこれは一行で設定変更できます。詳しくは、次の記事で紹介しています。

≫Matplotlib デフォルトの色の変更|実は一行でできます!
Matplotlibでグラフを描くと、デフォルトで青→オレンジ→緑→…と色が変わっていきます。この記事では、`Matplotlib`のデフォルトの色(カラーサイクル)の設定変更について紹介していきます。①データが10系列以上あるときに、また青に戻ってしまう場合の対応方法②自分好みにカラーサイクルを変更する方法また、デフォルトの色を指定して使用する方法についても触れています。
www.yutaka-note.com/entry/matplotlib_color_cycle
 

各系列を別のグラフとして作成

各系列をそれぞれ別のグラフにする場合には、サブプロット機能を利用します。

plt.subplot()でサブプロットを作成する場合は、次の記事を参考にしてください。

≫Matplotlib subplotの使い方徹底図解!|一つの図に複数グラフを描く
Matplotlibで一つの図の中に複数のグラフを並べるにはどうすればいいの?subplotでグラフを並べられるらしいけど、使い方がよくわからない!という方のために、「plt.subplot()の基本的な使い方」を画像付きで解説していきます!plt.subplot()でプロットをキレイに配置して、見やすく人に伝わるグラフを目指しましょう!
www.yutaka-note.com/entry/2020/01/02/232925
 

オブジェクト指向で、plt.subplots()を使用する場合は、次の記事を参考にしてください。

≫Matplotlib plt.subplots()の使い方|FigureとAxesを同時生成!
Matplotlibでグラフを描くとき「fig, ax = plt.subplots()って、よく見るけど何してるの?」「plt.subplots()の便利な使い方を知りたい! 」という方のために、plt.subplots()でFigureとAxesを作ると何が便利なのか、plt.subplots()の基本的な使い方、覚えておくと便利なplt.subplots()の引数をを図解付きで解説します!
www.yutaka-note.com/entry/matplotlib_subplots
 

凡例の作成方法

凡例の作成方法は、他のグラフと同様です。

次の記事を参考にしてください。

≫Matplotlib plt.legend() | 凡例の位置とスタイル設定完璧ガイド!
Matplotlibでは、デフォルトでは凡例は表示されません。「凡例(legend)を表示するにはどうしたらいいの?!」「凡例の位置や見た目の設定方法がわからない!」という方向けに、「凡例を表示する関数plt.legend()の使い方」「引数で位置や見た目を簡単に設定する方法」を紹介していきます。自分の作りたい凡例を作れるようになりましょう!
www.yutaka-note.com/entry/matplotlib_legend
 

オススメ|matplotlibとデータ分析の勉強方法

今回は、Matplotlibの軸・目盛り・目盛り線の設定について基本的なものを解説しました。

matplotlibは奥の深いモジュールですが、なかなかわかりにくい部分もあります…。

そこで、グラフの作成方法、種類変更、凡例、タイトルの設定など網羅的にわかりやすく整理した記事を作りました。ぜひ参考にしてみてください。

≫【初心者向け】Matplotlibの特徴と使い方をわかりやすく解説!
脱初心者のためのMatplotlibマスターガイドです。そもそもどういう流れでプロットするのか?どんな種類のグラフが描けるのか?日本語設定は?タイトルや軸の設定は?オブジェクト指向って何?そんな疑問を解決します!この記事で、脱Matplotlib初心者を目指そう!
www.yutaka-note.com/entry/matplotlib_guid
 

また、データ分析初心者の方にはこちらの記事もおススメです。

私がこれまで勉強してきた経験をもとに考えたおススメの勉強本の紹介記事です。

何から始めて、どうやってレベルアップしていけばいいのか、初心者の方にぜひおススメしたい本を紹介しました。

≫独学でデータ分析を勉強するオススメ学習本
独学でのpythonデータ分析勉強に役立ったおススメ書籍を紹介していきます。業務でそれなりにデータ分析を行えるまで、いろいろな試行錯誤をしてきましたが、もし自分が今ゼロから勉強する立場ならどうするのがいいのか考えてみました。以下では、入門書、個別モジュール用、実践用の3つの視点でおススメ本を紹介していきます。
www.yutaka-note.com/entry/data_analysis