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()
の必須の引数は次の通りです。
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
の高さの四角形が配置されて棒グラフになっていますね。
Matplotlib
のplt.bar()
の本質は
- 四角形を棒グラフになるように設置してくれる機能
だと考えると、納得がいくと思います。
ラベル名に文字列を設定
棒グラフを作成する場合、横軸にラベル名を設定したい場合がほとんどだと思います。
横軸にラベル名を設定するには、まずラベル名のリストを用意します。
labels = ["ラベル名1", "ラベル名2","ラベル名3",…]
その後、次のどちらかの方法で設定します。
- 棒グラフ作成時に引数で指定|
plt.bar(x, height, tick_label=labels)
- 棒グラフ作成後にラベルを更新|
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()
などの軸周りの設定に関しては、次の記事でまとめています。
オブジェクト指向の場合、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()
【参考】色の設定について詳しく知りたい方はこちらをチェック!
枠線の太さ
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 (完全透明)~1 (不透明) |
|
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
の値を与えると対応する値が自動で生成される
カラーマップを含めた色の詳細については、次の記事でまとめています。
棒の透明度
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系列のグラフ作成|
width
とalign
の組み合わせ - 複数系列のグラフテンプレート
の順番で解説します。
棒の配置変更
キーワード引数align
で、x
の値のどの位置に棒を配置するかを調整できます。
キーワード | 値 | 設定内容 |
---|---|---|
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
マスターを目指す皆さんへの次のおススメコンテンツはこちらです!
Twitter@YutaKaでは、ほぼ毎日pythonに関する情報を発信しています。
気楽にツイートしているので、気軽にフォローしてください!