YutaKaのPython教室

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

Matplotlib 棒グラフを徹底解説|複数系列・積み上げ棒グラフ全てOK

Pythonでグラフを描くときは、Matplotlibを使うことが多いですが、

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

という方のために、

  • Matplotlib棒グラフの作成・グラフ要素の設定

についてまとめしました。

私自身も今回紹介する内容を覚えてからは、Matplotlibでサラッと棒グラフを作れるようになっています!

 

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

Matplotlibで棒グラフを作成する際には、

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

を使用します。

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

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

基本的な棒グラフの作成

超基本的な棒グラフの作成には、

  • plt.bar(x, heigh)でプロットを生成
  • plt.show()でプロトを表示

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

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

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

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

%matplotlib inline
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の高さの四角形が配置されて棒グラフになっていますね。

Matplotlibplt.bar()の本質は

  • 四角形を棒グラフになるように設置してくれる機能

だと考えると、納得がいくと思います。

ラベル名に文字列を設定

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

横軸にラベル名を設定するには、まずラベル名のリストを用意します。

  • 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)
plt.show()

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.show()

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

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

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

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

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

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

棒の枠線の見た目変更

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

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

枠線の色

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

  • 色名などの文字列単体:グラフ全体に適用
  • 色名などのリスト:各棒の枠線に適用
plt.bar(x, height, edgecolor="lime") 
 
plt.show()

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

【参考】色の設定について詳しく知りたい方はこちらをチェック!

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

枠線の太さ

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

  • 数値pt:グラフ全体に適用
  • 数値ptのリスト:各棒の枠線に適用
plt.bar(x, height, edgecolor="black", linewidth=5) 
 
plt.show()画像

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

plt.show()

枠線のスタイル

linestyleにスタイルを、'-', '--', '-.', ': ', で指定します。

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

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

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

棒の見た目変更

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

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

棒の太さ

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

  • デフォルト値:width = 0.8

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

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

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

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

棒の色

facecolor(またはcolor, fc)に色名または[色名などのリスト]を渡します。

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

色名を文字列単体で渡して、全体適用してみます。

plt.bar(x, height, color = "lightblue") 
 
plt.show()

色名をリストで渡して、各棒に個別適用してみます。

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

全体の色を変更する場合には、カラーマップを適用すると便利です。

例えば、棒の高さに応じて色を濃くする設定などが簡単にできます

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(np.linspace(0, 1, len(x))) # 棒の高さに応じた色を生成
 
plt.bar(x, height, color = color)
 
plt.show()

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

カラーマップとは…

  • Matplotlibに組み込まれた色のセット
  • 0から1の値を与えると対応する値が自動で生成される

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

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

棒の透明度

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

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

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

plt.bar(x, height, alpha=0.5)<br /> 
plt.show()

棒の柄(テクスチャ)

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

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

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

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

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)
 
plt.show()

文字列の繰り返しなので、"/"*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)

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

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

  • 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)
 
plt.show()

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

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

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

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

の順番で解説します。

棒の配置変更

キーワード引数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")
plt.show()

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

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

2系列の棒グラフを作成する場合は、

  • align = 'edge'
  • 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)
 
plt.show()

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

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

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

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

  • 各棒の配置位置|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)
 
plt.show()

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

おわりに:Matplotlib関連記事の紹介

今回は、Matplotlibの棒グラフの作成方法を解説しました。

Matplotlibマスターを目指す皆さんへの次のおススメコンテンツはこちらです!

≫matplotlib inline の謎解明! |「書けと言われたので書いています」から卒業
≫matplotlib inline の謎解明! |「書けと言われたので書いています」から卒業
Jupyter Notebookでmatplotlibを使用する場合には、インポートする前に%matplotlib inlineと記述します。なぜinlineと入力しているのでしょうか?この記事では、matplotlib inlineの謎について解説していきたいと思います!
www.yutaka-note.com/entry/matplotlib_inline
 
≫matplotlib pyplot.text |matplotlibのテキスト表示をマスターせよ!
≫matplotlib pyplot.text |matplotlibのテキスト表示をマスターせよ!
グラフ内にテキストでコメントを記入することってよくありますよね?グラフにコメントがあると、グラフの大事な部分を強調して説明できます。この記事では、matplotlibでグラフ内にテキストを表示する方法、テキストの見た目の変更方法について図解・サンプルコード付きで解説しています!
www.yutaka-note.com/entry/2020/01/08/080413
 
≫matplotlib color 色の指定 | 一文字指定からカラーマップの使い方まで徹底解説
≫matplotlib color 色の指定 | 一文字指定からカラーマップの使い方まで徹底解説
伝わるグラフを作るためのポイントはなんでしょうか?いかに視覚的にわかりやすいか、これが大切です。それには重要な要素に色をつけて、視覚的にうったえることが超大切!この記事では、matplotlibでの色の指定方法について、基本から応用まで徹底解説!
www.yutaka-note.com/entry/matplotlib_color
 
≫Matplotlib 軸周り完璧マスターガイド | 軸・軸目盛・目盛り線の設定
≫Matplotlib 軸周り完璧マスターガイド | 軸・軸目盛・目盛り線の設定
Matplotlibで大変なのが軸周りの設定!グラフの「この要素」を変更するには、「どのメソッド」を使えばいいのかわからない…。という方のために、Matplotlibの軸・目盛り・目盛り線の設定について総まとめしました!これで軸周りの設定がだいぶ楽になります。軸周り完ぺきマスターガイド!
www.yutaka-note.com/entry/matplotlib_axis
 

Twitter@YutaKaでは、ほぼ毎日pythonに関する情報を発信しています。

気楽にツイートしているので、気軽にフォローしてください!