Python グラフ描画 Matplotlibの使い方【初心者向け完全保存版】

Python

改訂版 Pythonユーザのための Jupyter[実践]入門 [ 池内 孝啓、片柳 薫子、@driller ]

 

こんにちは、monachan_papa です。
今回はグラフ描画ができるライブラリ、Matplotlib の基礎について解説します。
グラフには「直線グラフ、折れ線グラフ、散布図、棒グラフ、円グラフ、ヒストグラム」など様々な種類があり、それだけでもう覚えるのが大変そう、というイメージがあります。
しかし、ベースとなるものが必ずあるわけで、それを押さえておけば理解のスピードが格段に違ってきます。

本テーマの目的は、各種グラフを使いこなすための根幹となる基礎をきっちり押さえることです。
本解説を読むことで以下の理解ができ、各種グラフを使いこなすための土台が身につきます。

  • Matplotlib におけるオブジェクトの概念
  • グラフ描画の基本フロー
  • グラフにおける汎用設定
  • 様々なグラフの基本的な作成方法

なお、Matplolib を使ってグラフを描くには、サブパッケージである Pyplot をインポートしておく必要があります。
慣例的に以下のように書きます。

import matplotlib.pyplot as plt

figure と axes

matplotlib でグラフ描画をする土台となるオブジェクトです。
以下、「大きな絵を描くこと」に例えて各オブジェクトの解説をします。

figure

figure は、「大きな額縁」と考えてください。
figure の生成は、慣例的に以下のようにします。

fig = plt.figure()

axes

axes は、「キャンバス」と考えてください。さきほど用意した大きな額縁の中に、キャンバスをセットする。そんなイメージです。
axes の生成は、慣例的に以下のようにします。

ax = fig.add_subplot(m行, n行, i番目)

上記は、「大きな額縁の中にとりあえず、キャンバス用のスペース m行 × n列 枚分を確保した。そして、その i番目にキャンバスをセットした。」という意味になります。

m, n, i の各数字は、0 始まりではありません!1始まりになります。

では、これをベースに「1行 × 1列 枚の1番目」の axes を生成します。つまり、単一の axes です。

# figure生成(大きな額縁を作る)
fig = plt.figure(facecolor='gray', figsize=(4, 3))

# figureに、axesを追加(大きな額縁に、キャンバスを追加)
ax = fig.add_subplot(1, 1, 1)

# /////今後、以下に何らかのグラフ描画設定/////
# グラフ描画設定のコード
#///////////////////////////////////////

# グラフ保存
plt.savefig('test.png')

# グラフ表示
plt.show()

  • figure 生成の引数指定で、色やサイズの設定ができます。
  • コード例ではグラフ描画なしですが、以降の解説で描画していきます。
  • 必要に応じて、plt.savefig(ファイル名) で保存します。
  • 一番最後に、plt.show() で表示します。

グラフ描画の基本フロー

さて、グラフ描画のコード行数が多めで、面倒くさいと思った御方もいらしゃるかもしれません。
実は、matplotlib には、もっと簡易的な書き方があります。しかし、本解説ではそれには触れません。

基本をマスターするまでは、以下のフロー通り忠実に行った方が、理解とマスタースピードも違うでしょう。

  1. figure の生成
  2. figure に axes を追加する
  3. axes に 何らかのグラフ描画設定をする
  4. 表示する

グラフ描画

では、いよいよグラフ描画をしていきます。まずは、一番簡単な直線グラフから。
単一グラフと複数グラフに分けて解説します。

単一グラフ

以下のコードは、1つの figureに、1つの axesを配置し、直線グラフを作成しています。

fig = plt.figure(facecolor='gray', figsize=(4, 3))
ax = fig.add_subplot(1, 1, 1)

# 対象データ
x = [0, 1, 2, 3, 4, 5]
y = x

# axに描画データを設定し、表示
ax.plot(x, y)
plt.show()

単一グラフ

ax.plot(x, y) のコードが、描画用のメソッドです。グラフの種類によって、メソッドが色々あります。のちほど詳しく解説しますので、今はこうやって動いているんだなあレベルで構いません。

複数グラフ

以下のコードは、1つの figureに 3行2列の axesを配置し、3番目の axesにのみ直線グラフを作成しています。

# figure生成
fig = plt.figure(facecolor='gray')

# 何行、何列、何番目
ax1 = fig.add_subplot(321)
ax1.set_title('1')

ax2 = fig.add_subplot(322)
ax2.set_title('2')

ax3 = fig.add_subplot(323)
ax3.set_title('3')

ax4 = fig.add_subplot(324)
ax4.set_title('4')

ax5 = fig.add_subplot(325)
ax5.set_title('5')

# axes間の余白調整
fig.subplots_adjust(wspace=0.5, hspace=1.5) # w:行方向、h:列方向

# 3番目のaxesだけプロット
x = [0, 1, 2, 3]
y = x
ax3.plot(x, y)

# 表示
plt.show()

複数グラフ

  • 何行、何列、何番目は、fig.add_subplot(321) のように、カンマ省略できます。(ただし、各数値が1桁に限る)
  • axesがどういう順番で配置されているか分かるように、タイトル設定をしました。
  • fig.subplots_adjustメソッドで、axes間の余白調整をしています。余白調整をコメントアウトして、再実行するとその違いがよく分かるはずです。

汎用的なグラフ描画設定

グラフには目的別に様々な種類や形状があれど、共通する描画設定もあります。
つまり、これを押さえておけば、あとは一歩一歩グラフ別のメソッドを覚えていけば良いわけです。

No メソッド 設定内容
1 axes.set_title(グラフタイトル) グラフタイトル
2 axes.legend(説明テキストリスト グラフの凡例
3 axes.grid(bool値) グリッドON/OFF
4 axes.set_xlabel(ラベル名) X軸のラベル
5 axes.set_ylabel(ラベル名) Y軸のラベル
6 axes.set_xlim(left=x0, right=x1) X軸の範囲
7 axes.set_ylim(bottom=y0, top=y1) Y軸の範囲
8 axes.set_xticks(目盛リスト) X軸の目盛
9 axes.set_yticks(目盛リスト) Y軸の目盛

以下のコードは、汎用的なグラフ設定です。

# figure生成
fig = plt.figure(facecolor='gray', figsize=(3, 4))

# figureにaxesを追加
ax = fig.add_subplot(111)

# y=xの比例グラフのプロット
x1 = [-2, -1, 0, 1, 2]
y1 = x1
ax.plot(x1, y1)

# y=2xの比例グラフのプロット
x2 = [-2, -1, 0, 1, 2] 
y2 = [-4, -2, 0, 2, 4]
ax.plot(x2, y2)

# 描画設定
ax.set_title('TEST', fontsize=18) # タイトル
ax.legend(['y=x', 'y=2x']) # 凡例
ax.grid(True) # girid表示ON
ax.set_xlabel('x', fontsize=14) # X軸ラベル
ax.set_ylabel('y', fontsize=14) # Y軸ラベル
ax.set_xlim(left=-2, right=2) # X範囲
ax.set_ylim(bottom=-4, top=4) # Y範囲
ax.set_xticks([-2, -1, 0, 1, 2]) # X軸目盛
ax.set_yticks([-4, -3, -2, -1, 0, 1, 2, 3, 4]) # X軸目盛

# 表示
plt.show()

汎用的なグラフ設定

 


改訂版 Pythonユーザのための Jupyter[実践]入門 [ 池内 孝啓、片柳 薫子、@driller ]

 

散布図

散布図の描画は、axes.scatter を使います。引数で、マーカーサイズ・色・形などの指定ができます。

メソッド

axes.scatter(x, y, その他オプション)

オプション例

No オプション 設定内容
1 x X座標データ配列
2 y Y座標データ配列
3 s サイズ
4 c
5 cmap カラーマップ
6 marker 形状
7 alpha 透明度(0〜1を指定、0:完全透明、1:不透明)
8 linewidth エッジ線の太さ
9 edgecolors エッジ線の色

マーカーの種類

No 記号 形状
1 .
2 o
3 * 星印
4 +
5 x
6 D ひし形

以下のコードは、乱数配列x,yを生成し、散布図としてプロットしています。

import numpy as np

# 対象データ
x = np.random.rand(100)
y = np.random.rand(100)

fig = plt.figure(facecolor='gray', figsize=(4, 3))
ax = fig.add_subplot(111)

# 散布図のプロット
sc = ax.scatter(
    x,
    y,
    s=50,
    alpha=0.5,
    linewidth=1,
    marker='o',
    c=np.random.rand(100),
    cmap='Blues',
    edgecolor='blue'
)

# カラーバー表示
plt.colorbar(sc)

plt.show()

散布図

  • plt.colorbar() の引数に、散布図を渡すと右にカラーバーが表示できます。
  • この色は、c=np.random.rand(100) で、乱数をもとに設定しています。

折れ線グラフ

折れ線グラフの描画は、axes.plot を使用します。引数で、線の種類・色・太さ・マーカーの種類などが指定できます。
なお、マーカーの種類は散布図と同じです。

メソッド

axes.plot(x, y, その他オプション)

オプション例

No オプション 設定内容
1 x X座標データ配列
2 y Y座標データ配列
3 fmt 線の種類(位置引数)
4 c 線の色
5 linewidth 線の太さ
6 alpha 透明度(0〜1を指定、0:完全透明、1:不透明)
7 marker 形状

線の種類

No 記号 形状
1 実線
2 破線
3 -. 点+破線
4 : 点線

以下のコードは、4種類の折れ線グラフを作成しています。

# 対象データ
x = [1, 2, 3, 4, 5]
y1 = [50, 150, 100, 250, 0]
y2 = [70, 200, 100, 300, 50]
y3 = [100, 100, 200, 400, 50]
y4 = [50, 200, 150, 300, 50]

fig = plt.figure(facecolor='gray', figsize=(4, 3))
ax = fig.add_subplot(111)

# 折れ線グラフのプロット(実線、破線、点+破線、点線)
ax.plot(x, y1, '-', c='red', linewidth=1, marker='*', alpha=1)
ax.plot(x, y2, '--', c='blue', linewidth=2, marker='o', alpha=0.5)
ax.plot(x, y3, '-.', c='green', linewidth=3, marker='D', alpha=0.5)
ax.plot(x, y4, ':', c='orange', linewidth=4, marker='x', alpha=0.7)

plt.show()

折れ線グラフ

棒グラフ

棒グラフの描画は、axes.bar を使用します。引数で、幅・ラベル・色などが指定できます。

メソッド

axes.bar(x, height, その他オプション)

オプション例

No オプション 設定内容
1 x X座標データ配列
2 height 棒の高さのデータ配列
3 width 棒の幅を数値指定。デフォルト0.8
4 bottom 棒の下側の位置を数値指定。デフォルト0
5 color 棒の色
6 edgecolor 棒の枠線色
7 linewidth 棒の枠線太さ
8 tick_label 横軸ラベル
9 align 棒の位置。edge、centerのどれかを指定。デフォルトcenter

以下のコードは、A〜Eの各値に対して、棒グラフを作成しています。

# 対象データ
label = list('ABCDE')
x = [1, 2, 3, 4, 5] # 横軸
height = [3, 5, 1, 2, 4] # 値

fig = plt.figure(facecolor='gray', figsize=(4, 3))
ax = fig.add_subplot(111)

# 棒グラフのプロット
ax.bar(x, height, tick_label=label, linewidth=1, edgecolor='black')

plt.show()

棒グラフ

円グラフ

円グラフの描画は、axes.pie を使用します。引数で、線の種類・色・太さ・マーカーの種類などが指定できます。

ここで注意点があります。引数のデフォルト値がかなり特殊です。
引数指定しない場合は円グラフの開始が、時計で言うところの3時の位置から反時計回りで描画されます。
よって、円グラフの一般的な作法である「12時の位置から時計回り」にするため、counterclock と startangle の指定をします。

また、環境次第で円が押し潰されてしまうため、axes.axis(‘equal’) を指定しています。

メソッド

axes.pie(x, その他オプション)

オプション例

No オプション 設定内容
1 x データ配列
2 labels 各要素のラベル配列
3 colors 各要素の色配列
4 autopct 構成割合をパーセント表示(デフォルト:None)
5 counterclock True:反時計回り、False:時計回り(デフォルト:True)
6 satartangle 開始角度(デフォルト:None、3時の位置から開始)

以下のコードは、A〜Eのデータの円グラフを作成しています。

# 対象データ
labels = list('ABCDE')
x = [40, 30, 15, 10, 5]

fig = plt.figure(facecolor='gray', figsize=(5, 3))
ax = fig.add_subplot(111)

# 円グラフのプロット(12時の位置から時計回り)
ax.pie(x, labels=labels, autopct='%.1f%%', counterclock=False, startangle=90)
ax.legend(labels)

# 補正してから表示
ax.axis('equal')
plt.show()

円グラフ

  • 構成割合の書式は小数点以下1桁の場合、autopct=’%.1f%%’ となります。もし2桁なら、’%.2f%%’ とします。

ヒストグラム(度数分布)

ヒストグラム(度数分布)の描画は、axes.hist を使用します。引数で、階級数・色などが指定できます。
引数 bins は、引数の型が何種類かあります。
整数を指定すると、その数の分の区間に分割します。一方、配列を指定すると、その配列の階級となります。

メソッド

axes.hist(x, その他オプション)

オプション例

No オプション 設定内容
1 x データ配列
2 bins 階級数 or 階級リスト or 階級の分割方式
3 destiny Trueの場合、ヒストグラムの面積が1となるように調整
4 color
5 ec 境界色
6 alpha 透明度(0〜1を指定、0:完全透明、1:不透明)

以下のコードは、平均0、標準偏差10、サンプル数100 の正規分布の乱数配列を生成し、ヒストグラムで表示しています。

import numpy as np

# 対象データ
x = np.random.normal(loc=0, scale=10, size=100)

fig = plt.figure(facecolor='gray', figsize=(4, 3))
ax = fig.add_subplot(111)

# ヒストグラムをプロット
ax.hist(x, bins=10, color='blue', ec='black', alpha=0.5)
#ax.hist(x, bins='auto', color='blue', ec='black', alpha=0.5)

plt.show()

ヒストグラム(度数分布)

階級数の自動設定

階級数は任意に決めることができます。しかし、決めるのに悩む場合、自動設定ができます。
引数指定で、bins=’auto’ にすると、スタージェスの公式とフリードマン=ダイアニコスの法則の計算結果のうち、階級数の大きい方が自動設定されます。


以上で、Matplotlib についての解説を終わります。

Matplotlib はデータの分析や解析で欠かせないライブラリなのに、入門レベルが意外に躓きやすいです。描画の基本フローをきっちりマスターしなければならないことの重要さがよく分かります。
そして、グラフ=可視化 故に、細かい設定まわりが膨大です。どんだけ覚えればええんやあ!ということになりかねません。
細かい設定まわりは、慣れてきたらほどほどに都度調べながら楽しくやっていきましょう。

しかしながら、可視化するということは楽しいです。ビジュアル的に訴えかけるものは見ていて楽しいですから。
私自身、可視化するのが本当に大好きです。

さて、慣れてきて、Matplotlib をもっともっと使いこなしたい御方、さらに多彩なグラフ描画にチャレンジしてみたい御方は、改訂版 Pythonユーザのための Jupyter[実践]入門 [ 池内 孝啓、片柳 薫子、@driller ]がオススメです。
JupyterLab のフル活用方法や、データ分析についても同時に学べて一石二鳥ならぬ、一石三鳥です。

 


改訂版 Pythonユーザのための Jupyter[実践]入門 [ 池内 孝啓、片柳 薫子、@driller ]

 

また、爆速で Matplotlibを含め、データ可視化・データ分析 を学びたい御方にはプログラミングスクールを考えるのも、ひとつの手です。独学よりも効果が出やすいですが、いかんせん投資がけっこうかかります。しかし、techgymというスクールは通うか通わないかは別として、無料のサンプルテキスト&解説動画がもらえます。これをとりあえず getしてまずは試しに体験学習するのもありでしょう。

コメント

タイトルとURLをコピーしました