Matplotlib
を使えば、様々な棒グラフを描くことができます。
とはいっても、実際に使ってみると次のような問題に直面することも…。
Matplotlib
で棒グラフを作成する方法がよくわからない…。- 棒グラフで悩むなら、
Matplotlib
あきらめてExcel使おうかな…。
そこで、今回は棒グラフについて、次の内容をわかりやすく解説しました。
Matplotlib
で棒グラフを描く基本的な方法- 棒グラフ要素の見た目変更方法
- 積み上げ棒グラフ、複数系列の棒グラフ作成方法
このあたりを網羅すると、Matplotlib
でサラッと棒グラフを作れるようになってきます!
- 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入門記事も参考にしてください。
また、fig, ax = plt.subplots()
で始まるオブジェクト指向プロットは、次の記事で解説しています。
基本的な棒グラフの作成|plt.bar()
超基本的な棒グラフの作成の流れは、次の通りです。
plt.bar(x, heigh)
でプロットを生成plt.show()
でプロットを表示(Notebookの場合は省略可能)
plt.bar()
の必須の引数は次の通りです。
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",…]
その後、次のどちらかの方法で設定します。
- 棒グラフ作成時に引数で指定|
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)
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()
などの軸周りの設定に関しては、次の記事でまとめています。
オブジェクト指向の場合、xticks()
でのラベル名変更方法が異なりますので注意してください(詳しくは上の記事で)。
また、ラベル名に日本語を使用したい場合には特別な設定が必要になります。次の記事を参考にしてください。
棒の枠線の見た目変更
棒の枠線の見た目は、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)
次のように各棒の枠線の色が個別に設定されています。
色の設定について詳しく知りたい方はこちらをチェックしてください。
枠線の太さ|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 (完全透明)~1 (不透明) |
hatch |
棒の柄 | '/' , '\', '|' , '-' , '+' , 'x' , 'o' , 'O' , '.' , '*' で指定 |
棒の太さ|width
width
に太さを、数値
ptで渡します。
width = 数値
(デフォルト:0.8
pt)
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
に組み込まれた色のセットです。
カラーマップを含めた色の詳細については、次の記事でまとめています。
棒の透明度|alpha
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
では、四角の図形を適切に配置することで、棒グラフにしています。
そのため、図形の見た目設定をよく理解すれば、棒グラフの設定をより細かく行うことができます。
図形の設定ついては、次の記事を参考にしてください。
積み上げ棒グラフの作成方法
積み上げ棒グラフを作成するには、次の手順を踏みます。
- 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()
- 【参考】凡例の設定については、次の記事を参考にしてください。
複数系列の棒グラフの作成方法
棒の配置align
、太さwidth
を変更して、複数系列の棒グラフを作成できます。
少しややこしい部分があるので、次の順番で一歩ずつ解説していきます。
- 棒の配置の変更|
align
- 2系列のグラフ作成|
width
とalign
の組み合わせ - 複数系列のグラフテンプレート
棒の配置変更|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")
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)
今回はベタ打ちですが、関数化して使っても便利ですね!
系列毎の色の変更方法
複数系列の場合、デフォルトでは系列毎に青→オレンジ→…と色が自動で変化していきます。
この色のサイクル(カラーサイクル)を変更したい場合は、カラーマップを使用すると便利です。
例えば、次のように淡い色合いに変えることも簡単です。
実はこれは一行で設定変更できます。詳しくは、次の記事で紹介しています。
各系列を別のグラフとして作成
各系列をそれぞれ別のグラフにする場合には、サブプロット機能を利用します。
plt.subplot()
でサブプロットを作成する場合は、次の記事を参考にしてください。
オブジェクト指向で、plt.subplots()
を使用する場合は、次の記事を参考にしてください。
凡例の作成方法
凡例の作成方法は、他のグラフと同様です。
次の記事を参考にしてください。
オススメ|matplotlibとデータ分析の勉強方法
今回は、Matplotlib
の軸・目盛り・目盛り線の設定について基本的なものを解説しました。
matplotlib
は奥の深いモジュールですが、なかなかわかりにくい部分もあります…。
そこで、グラフの作成方法、種類変更、凡例、タイトルの設定など網羅的にわかりやすく整理した記事を作りました。ぜひ参考にしてみてください。
また、データ分析初心者の方にはこちらの記事もおススメです。
私がこれまで勉強してきた経験をもとに考えたおススメの勉強本の紹介記事です。
何から始めて、どうやってレベルアップしていけばいいのか、初心者の方にぜひおススメしたい本を紹介しました。