Matplotlib は Python でデータの可視化やグラフ描画を行うための最も標準的な外部ライブラリです。Matplotlib は豊富な機能を備えており、折れ線グラフ、ヒストグラム、散布図、バーチャートなど、さまざまな種類のグラフを作成することができます。本ページでは Matplotlib の基本的な使い方を簡単に説明します。
Matplotlib は次のコマンドで必要なパッケージをすべてインストールすることができます。
(.venv) $ pip install matplotlib
(.venv) $ pip freeze | grep matplotlib matplotlib==3.11.1
コマンド pip は仮想環境下で実行する必要があります。仮想環境については拙作のページ 仮想環境とパッケージ を参考にしてください。M.Hiroi がインストールしたのは ver 3.11.1 (2026 年 8 月時点) です。Matplotlib はインストールされているがバージョンが古い場合、次のコマンドでパッケージをアップグレードすることができます。
(.venv) $ pip install --upgrade matplotlib
プログラミング言語によっては、ブラウザ上で手軽に試せる実行環境 (playground) が用意されているものがあります。もちろん、Python にも playground があります。そのうちの一つ Google Colaboratory (通称 : Colab) は、Google が提供するブラウザ上で動作する無料の Python 実行環境です。Google アカウントとブラウザ (Chrome など) があれば、すぐに Python のプログラムを実行することができます。
Colab は GPU / TPU を無料で利用できるので、AI やディープラーニングのほうに目が行きがちですが、NumPy, SymPy, Matplotlib など便利なライブラリもプリインストールされているので、import するだけで簡単に利用することができます。
なお、Colab の無料版には使用に制限がありますが、それを緩和した有料版も用意されています。学習目的で Colab を利用するのであれば、無料版の機能で十分なように思います。
Colab の基本的な使い方は簡単です。
まず最初に matplotlib をインポートしてください。
>>> import matplotlib.pyplot as plt >>> import numpy as np >>>
グラフの作成やカスタマイズを行うための主要な関数が詰まった pyplot モジュールを、短い別名 (エイリアス) の plt として読み込むのが慣例です。
Matplotlib には、「MATLAB スタイル」と「オブジェクト指向スタイル」という 2 つの異なる記述方法が存在します。MATLAB スタイル は plt に対して直接命令を出す、数値解析ソフト「MATLAB」に似た記述方法です。関数 plt.plot() にデータを渡すだけでグラフを表示することができます。
plt.plot(x, y)
x, y はリスト (または NumPy の配列) を渡します。plt.plot() はグラフを表すオブジェクト (グラフオブジェクト) を返します。そして、関数 plt.show() を実行するとグラフが描画されます。簡単な実行例を示します。
>>> x = range(1, 11)
>>> x
range(1, 11)
>>> y = np.random.rand(10)
>>> y
array([0.41830429, 0.68111168, 0.40744786, 0.42240967, 0.43904559,
0.53804625, 0.87124891, 0.38856062, 0.59236151, 0.05327839])
>>> plt.plot(x, y)
[<matplotlib.lines.Line2D object at 0x7d222ddcdac0>]
>>> plt.show()
折れ線グラフ
既存のグラフにデータを追加する場合も plt.plot() をそのまま使用します。簡単な例として sin(x), cos(x) のグラフを描画してみましょう。
>>> x = np.linspace(0, 2 * np.pi, 100) >>> plt.plot(x, np.sin(x)) [<matplotlib.lines.Line2D object at 0x7d222d265010>] >>> plt.plot(x, np.cos(x)) [<matplotlib.lines.Line2D object at 0x7d222d2810a0>] >>> plt.show()
サインとコサイン
Matplotlib を使って関数を描画する場合、NumPy を使って x 軸の連続したデータを生成するのが一般的な方法です。上記の例では、x の範囲を 0 から 2π まで設定しています。
このように、MATLAB スタイルはシンプルなグラフを手早く作成できるので便利ですが、複数のグラフを並べるといった複雑なレイアウトを作成するには不向きです。このような場合、オブジェクト指向スタイル (oo-style) のほうが適しています。
オブジェクト指向スタイルはグラフ全体を表す台紙 (Figure) と、実際のグラフを描く座標軸・部品 (Axes) という「オブジェクト」を明示的に作成して操作します。設定対象が明確になるため、コードが乱雑にならず、細かなレイアウト調整が容易になります。
最も標準的な方法は plt.subplots() を使うことです。
fig, ax = plt.subplots()
subplots() は Figure と Axes を返すので、それらを変数 fig, ax で受け取ります。そして、ax.描画関数() でグラフを描画することができます。
>>> fig, ax = plt.subplots()
>>> fig
<Figure size 640x480 with 1 Axes>
>>> ax
<Axes: >
>>> x = range(1, 11)
>>> x
range(1, 11)
>>> y = np.random.rand(10)
>>> y
array([0.52538968, 0.96000353, 0.92227889, 0.78455527, 0.66550494,
0.77575586, 0.31627685, 0.70189416, 0.72996606, 0.55613739])
>>> ax.plot(x, y)
[<matplotlib.lines.Line2D object at 0x71812ec51100>]
>>> plt.show()
折れ線グラフ (2)
画像は関数 savefig() で保存することができます。グラフを表示する plt.show() の直前に記述します。
plt.savefig(ファイル名)
拡張子に応じた形式 (PNG, PDF, SVG など) で保存することができます。dpi=数値 で解像度を指定することができます。なお、GUI からでも画像をセーブすることが可能です。
Matplotlib では、グラフの見た目や挙動をカスタマイズするために、描画関数には多くの引数が用意されています。Matplotlib ではこれを「属性 (Attributes)」と呼んでいます。よく使われる属性を以下に示します。
タイトルと x, y 軸名は関数 (またはメソッド) で指定します。
よく用いられる描画関数を以下に示します。
このほかにも、Matplotlib にはたくさんの属性やグラフが用意されています。詳細は本家のドキュメントをお読みくださいませ。
Matplotlib で日本語が文字化けする場合、ライブラリ japanize-matplotlib をインストールしてインポートするだけで、簡単に解決することができます。
(.venv) $ pip install japanize-matplotlib
リスト : 日本語の表示 import matplotlib.pyplot as plt import japanize-matplotlib ... 略 ...
もしかすると、以下に示すようなエラーが発生するかもしれません。
ModuleNotFoundError: No module named 'distutils'
この場合、japanize-matplotlib をアンインストールして、ライブラリ setuptools をインストールしてください。
(.venv) $ pip install --upgrade setuptools
その後、再度 japanize-matplotlib をインストールすると日本語が表示されるようになります。
追加のライブラリを入れたくない場合は、コード内で plt.rcParams を使ってお使いの OS に搭載されている日本語フォントを指定します。
リスト : 日本語の表示 (2) import matplotlib.pyplot as plt plt.rcParams['font.family'] = 'Noto Sans CJK JP' ... 略 ...
M.Hiroi は Google と Adobe が開発した Noto フォントを使っています。Linux の場合、次のコマンドでインストールされている日本語フォントの一覧を表示することができます。
fc-list :lang=ja
この他に、よく使われる日本語フォントとして、IPAexゴシック / IPAex明朝 や VLゴシック などがあります。お好きなフォントを選んでください。
折れ線グラフの簡単な例題として、東京都の 2024 年度月平均気温 を Matplotlib で表示してみましょう。
リスト : 折れ線グラフ
import matplotlib.pyplot as plt
import numpy as np
# 月平均気温
ys1 = [7.1, 8.0, 9.6, 17.1, 20.0, 23.1, 28.7, 29.0, 26.6, 20.6, 13.7, 8.1]
# 月平均最高気温
ys2 = [11.8, 12.5, 14.8, 21.8, 24.8, 27.7, 33.5, 33.6, 30.9, 24.5, 17.8, 13.2]
# 月平均最低気温
ys3 = [2.9, 4.1, 5.1, 13.1, 15.6, 19.3, 25.0, 25.7, 23.5, 17.4, 10.2, 3.8]
# 月
x = range(1, 13)
# 描画
plt.plot(x, ys1, lw=2, marker = 'o', label = "avg")
plt.plot(x, ys2, lw=2, marker = 'o', label = "max")
plt.plot(x, ys3, lw=2, marker = 'o', label = "min")
plt.xlim(0, 13)
plt.ylim(0, 40)
plt.xticks(range(1, 13, 1))
plt.title('Average temperature in 2024')
plt.xlabel('Month')
plt.ylabel('Celsius')
plt.legend()
plt.show()
折れ線グラフ
リスト : 折れ線グラフ (オブジェクト指向スタイル)
import matplotlib.pyplot as plt
import numpy as np
# 月平均気温
ys1 = [7.1, 8.0, 9.6, 17.1, 20.0, 23.1, 28.7, 29.0, 26.6, 20.6, 13.7, 8.1]
# 月平均最高気温
ys2 = [11.8, 12.5, 14.8, 21.8, 24.8, 27.7, 33.5, 33.6, 30.9, 24.5, 17.8, 13.2]
# 月平均最低気温
ys3 = [2.9, 4.1, 5.1, 13.1, 15.6, 19.3, 25.0, 25.7, 23.5, 17.4, 10.2, 3.8]
# 月
x = range(1, 13)
fig, ax = plt.subplots()
# 描画
ax.plot(x, ys1, lw=2, marker = 'o', label = "avg")
ax.plot(x, ys2, lw=2, marker = 'o', label = "max")
ax.plot(x, ys3, lw=2, marker = 'o', label = "min")
ax.set_xlim(0, 13)
ax.set_ylim(0, 40)
ax.set_xticks(range(1, 13, 1))
ax.set_title('Average temperature in 2024')
ax.set_xlabel('Month')
ax.set_ylabel('Celsius')
ax.legend()
plt.show()
ある学年の生徒 100 人の身長を計測したとしましょう。ここでは、現実のデータではなく、乱数で作成した仮想的なデータを用います。
リスト : 身長のデータ
height = [
148.7, 149.5, 133.7, 157.9, 154.2, 147.8, 154.6, 159.1, 148.2, 153.1,
138.2, 138.7, 143.5, 153.2, 150.2, 157.3, 145.1, 157.2, 152.3, 148.3,
152.0, 146.0, 151.5, 139.4, 158.8, 147.6, 144.0, 145.8, 155.4, 155.5,
153.6, 138.5, 147.1, 149.6, 160.9, 148.9, 157.5, 155.1, 138.9, 153.0,
153.9, 150.9, 144.4, 160.3, 153.4, 163.0, 150.9, 153.3, 146.6, 153.3,
152.3, 153.3, 142.8, 149.0, 149.4, 156.5, 141.7, 146.2, 151.0, 156.5,
150.8, 141.0, 149.0, 163.2, 144.1, 147.1, 167.9, 155.3, 142.9, 148.7,
164.8, 154.1, 150.4, 154.2, 161.4, 155.0, 146.8, 154.2, 152.7, 149.7,
151.5, 154.5, 156.8, 150.3, 143.2, 149.5, 145.6, 140.4, 136.5, 146.9,
158.9, 144.4, 148.1, 155.5, 152.4, 153.3, 142.3, 155.3, 153.1, 152.3
]
数値を並べただけではデータの特徴を把握することは難しいので、これを表にまとめます。たとえば、130 cm から 5 cm 間隔でデータの個数を求めると、次のようになります。
| 階級 | 階級値 | 度数 | 累積度数 |
|---|---|---|---|
| 130 - 135 | 132.5 | 1 | 1 |
| 135 - 140 | 137.5 | 6 | 7 |
| 140 - 145 | 142.5 | 12 | 19 |
| 145 - 150 | 147.5 | 25 | 44 |
| 150 - 155 | 152.5 | 32 | 76 |
| 155 - 160 | 157.5 | 17 | 93 |
| 160 - 165 | 162.5 | 6 | 99 |
| 165 - 170 | 167.5 | 1 | 100 |
階級はデータの範囲を表します。この表では x cm 以上 y cm 未満を x - y で表しています。階級値は階級 x - y の中央値 (x + y) / 2 のことです。度数はその階級に出現したデータの個数です。度数を示してある表のことを「度数分布表」といいます。累積度数はその階級までの度数を全部加えたものです。累積度数を示してある表を「累積度数分布表」といいます。
そして、度数分布表を棒グラフで表したものを「ヒストグラム」といいます。Matplotlib を使って棒グラフを作成すると、次のようになります。
リスト : ヒストグラム (1)
import matplotlib.pyplot as plt
import numpy as np
bins = ['130-135', '135-140', '140-145', '145-150', '150-155', '155-160', '160-165', '165-170']
count = [1, 6, 12, 25, 32, 17, 6, 1]
plt.bar(bins, count, label='Frequency')
plt.title('Frequency')
plt.legend()
plt.show()
ヒストグラム (1)
リスト : ヒストグラム (オブジェクト指向スタイル)
import matplotlib.pyplot as plt
import numpy as np
bins = ['130-135', '135-140', '140-145', '145-150', '150-155', '155-160', '160-165', '165-170']
count = [1, 6, 12, 25, 32, 17, 6, 1]
fig, ax = plt.subplots()
ax.bar(bins, count, label='Frequency')
ax.set_title('Frequency')
ax.legend()
plt.show()
関数 hist() を使うと、もっと簡単にヒストグラムを作成することができます。
リスト : ヒストグラム (2)
import matplotlib.pyplot as plt
import numpy as np
height = [
148.7, 149.5, 133.7, 157.9, 154.2, 147.8, 154.6, 159.1, 148.2, 153.1,
138.2, 138.7, 143.5, 153.2, 150.2, 157.3, 145.1, 157.2, 152.3, 148.3,
152.0, 146.0, 151.5, 139.4, 158.8, 147.6, 144.0, 145.8, 155.4, 155.5,
153.6, 138.5, 147.1, 149.6, 160.9, 148.9, 157.5, 155.1, 138.9, 153.0,
153.9, 150.9, 144.4, 160.3, 153.4, 163.0, 150.9, 153.3, 146.6, 153.3,
152.3, 153.3, 142.8, 149.0, 149.4, 156.5, 141.7, 146.2, 151.0, 156.5,
150.8, 141.0, 149.0, 163.2, 144.1, 147.1, 167.9, 155.3, 142.9, 148.7,
164.8, 154.1, 150.4, 154.2, 161.4, 155.0, 146.8, 154.2, 152.7, 149.7,
151.5, 154.5, 156.8, 150.3, 143.2, 149.5, 145.6, 140.4, 136.5, 146.9,
158.9, 144.4, 148.1, 155.5, 152.4, 153.3, 142.3, 155.3, 153.1, 152.3
]
plt.hist(height, label = 'Frequency')
plt.title('Frequency')
plt.legend()
# オブジェクト指向スタイル
# fig, ax = subplots()
# ax.hist(height, label = 'Frequency')
# ax.set_title('Frequency')
# ax.legend()
plt.show()
ヒストグラム (2)
cumulative=True を指定すると累積度数を表示することもできます。
リスト : 度数分布と累積度数
import matplotlib.pyplot as plt
import numpy as np
height = [
148.7, 149.5, 133.7, 157.9, 154.2, 147.8, 154.6, 159.1, 148.2, 153.1,
138.2, 138.7, 143.5, 153.2, 150.2, 157.3, 145.1, 157.2, 152.3, 148.3,
152.0, 146.0, 151.5, 139.4, 158.8, 147.6, 144.0, 145.8, 155.4, 155.5,
153.6, 138.5, 147.1, 149.6, 160.9, 148.9, 157.5, 155.1, 138.9, 153.0,
153.9, 150.9, 144.4, 160.3, 153.4, 163.0, 150.9, 153.3, 146.6, 153.3,
152.3, 153.3, 142.8, 149.0, 149.4, 156.5, 141.7, 146.2, 151.0, 156.5,
150.8, 141.0, 149.0, 163.2, 144.1, 147.1, 167.9, 155.3, 142.9, 148.7,
164.8, 154.1, 150.4, 154.2, 161.4, 155.0, 146.8, 154.2, 152.7, 149.7,
151.5, 154.5, 156.8, 150.3, 143.2, 149.5, 145.6, 140.4, 136.5, 146.9,
158.9, 144.4, 148.1, 155.5, 152.4, 153.3, 142.3, 155.3, 153.1, 152.3
]
plt.hist(height, label = 'cumulative', cumulative=True, edgecolor='black')
plt.title('cumulative')
plt.legend()
# オブジェクト指向スタイル
# fig, ax = plt.subplots()
# ax.hist(height, label = 'cumulative', cumulative=True, edgecolor='black')
# ax.set_title('cumulative')
# ax.legend()
plt.show()
累積度数
Matplotlib で横棒グラフを描くには、関数 barh() を使うと簡単です。
リスト : 横棒グラフ
import matplotlib.pyplot as plt
import numpy as np
bins = ['130-135', '135-140', '140-145', '145-150', '150-155', '155-160', '160-165', '165-170']
count = [1, 6, 12, 25, 32, 17, 6, 1]
plt.barh(bins, count, label='Frequency')
plt.title('Frequency')
plt.legend()
plt.show()
横棒グラフ
リスト : 横棒グラフ (オブジェクト指向スタイル)
import matplotlib.pyplot as plt
import numpy as np
bins = ['130-135', '135-140', '140-145', '145-150', '150-155', '155-160', '160-165', '165-170']
count = [1, 6, 12, 25, 32, 17, 6, 1]
fig, ax = plt.subplots()
ax.barh(bins, count, label='Frequency')
ax.set_title('Frequency')
ax.legend()
plt.show()
一方が増加するときに他方も増加傾向が見られる場合を「正の相関」があるといい、他方に減少傾向が見られる場合を「負の相関」があるといいます。また、相関関係が明瞭な場合を「強い相関」といい、不明瞭な場合を「弱い相関」といいます。文章で説明してもわかりにくいのて、図に示すことにしましょう。
たとえば、次の配列に示す対のデータ [x, y] が 30 個あります。
リスト : 対のデータ (1)
# 強い正の相関
data1 = [
[4.6, 5.5], [0.0, 1.7], [6.4, 7.2], [6.5, 8.3],
[4.4, 5.7], [1.1, 1.1], [2.8, 4.1], [5.1, 6.7],
[3.4, 5.0], [5.8, 6.6], [5.7, 6.3], [5.5, 5.6],
[7.9, 8.7], [3.0, 3.6], [6.8, 8.2], [6.2, 6.2],
[4.0, 5.0], [8.6, 9.5], [7.5, 8.9], [1.3, 2.6],
[6.3, 7.4], [3.1, 5.0], [6.1, 8.2], [5.3, 6.6],
[3.9, 5.1], [5.8, 7.0], [2.6, 3.5], [4.8, 6.3],
[2.2, 2.9], [5.3, 6.9]
]
これを平面上にプロットしたものを「相関図 (correlation diagram)」とか「散布図」といいます。散布図は関数 scatter() で簡単に作成することができます。
リスト : 散布図 (1)
import matplotlib.pyplot as plt
import numpy as np
# 強い正の相関
data1 = [
[4.6, 5.5], [0.0, 1.7], [6.4, 7.2], [6.5, 8.3],
[4.4, 5.7], [1.1, 1.1], [2.8, 4.1], [5.1, 6.7],
[3.4, 5.0], [5.8, 6.6], [5.7, 6.3], [5.5, 5.6],
[7.9, 8.7], [3.0, 3.6], [6.8, 8.2], [6.2, 6.2],
[4.0, 5.0], [8.6, 9.5], [7.5, 8.9], [1.3, 2.6],
[6.3, 7.4], [3.1, 5.0], [6.1, 8.2], [5.3, 6.6],
[3.9, 5.1], [5.8, 7.0], [2.6, 3.5], [4.8, 6.3],
[2.2, 2.9], [5.3, 6.9]
]
xs = [x[0] for x in data1]
ys = [x[1] for x in data1]
plt.scatter(xs, ys, label='Data1')
plt.title('Simple Scatter Plot')
plt.legend()
plt.show()
散布図 (1)
横軸を x, 縦軸を y とすると、x が増加すると y も増加していることが一目でわかります。これが正の相関です。そして、点がある直線上に並んでいることもわかるでしょう。強い相関性を示しています。
リスト : 対のデータ (オブジェクト指向スタイル)
import matplotlib.pyplot as plt
import numpy as np
# 強い正の相関
data1 = [
[4.6, 5.5], [0.0, 1.7], [6.4, 7.2], [6.5, 8.3],
[4.4, 5.7], [1.1, 1.1], [2.8, 4.1], [5.1, 6.7],
[3.4, 5.0], [5.8, 6.6], [5.7, 6.3], [5.5, 5.6],
[7.9, 8.7], [3.0, 3.6], [6.8, 8.2], [6.2, 6.2],
[4.0, 5.0], [8.6, 9.5], [7.5, 8.9], [1.3, 2.6],
[6.3, 7.4], [3.1, 5.0], [6.1, 8.2], [5.3, 6.6],
[3.9, 5.1], [5.8, 7.0], [2.6, 3.5], [4.8, 6.3],
[2.2, 2.9], [5.3, 6.9]
]
xs = [x[0] for x in data1]
ys = [x[1] for x in data1]
fig, ax = plt.subplots()
ax.scatter(xs, ys, label='Data1')
ax.set_title('Simple Scatter Plot')
ax.legend()
plt.show()
もちろん、複数のデータを表示することもできます。
リスト : 対のデータ (2)
import matplotlib.pyplot as plt
import numpy as np
# 強い正の相関
data1 = [
[4.6, 5.5], [0.0, 1.7], [6.4, 7.2], [6.5, 8.3],
[4.4, 5.7], [1.1, 1.1], [2.8, 4.1], [5.1, 6.7],
[3.4, 5.0], [5.8, 6.6], [5.7, 6.3], [5.5, 5.6],
[7.9, 8.7], [3.0, 3.6], [6.8, 8.2], [6.2, 6.2],
[4.0, 5.0], [8.6, 9.5], [7.5, 8.9], [1.3, 2.6],
[6.3, 7.4], [3.1, 5.0], [6.1, 8.2], [5.3, 6.6],
[3.9, 5.1], [5.8, 7.0], [2.6, 3.5], [4.8, 6.3],
[2.2, 2.9], [5.3, 6.9]
]
# 強い負の相関
data2 = [
[6.1, 3.7], [3.9, 7.5], [8.6, 1.7], [5.9, 3.9],
[3.5, 5.5], [7.0, 2.4], [0.9, 9.8], [0.0, 10.2],
[5.2, 4.2], [3.5, 6.5], [6.9, 3.2], [4.3, 5.9],
[5.0, 5.9], [7.4, 3.3], [3.1, 6.6], [4.0, 6.2],
[6.9, 2.9], [4.8, 5.0], [10.6, 0.0], [4.7, 4.3],
[2.9, 7.6], [7.2, 2.2], [3.6, 6.0], [5.5, 4.3],
[5.5, 4.5], [6.9, 3.2], [5.8, 3.6], [4.8, 4.6],
[7.3, 2.5], [4.7, 5.4]
]
xs1 = [x[0] for x in data1]
ys1 = [x[1] for x in data1]
xs2 = [x[0] for x in data2]
ys2 = [x[1] for x in data2]
plt.scatter(xs1, ys1, label='Data1')
plt.scatter(xs2, ys2, label='Data2')
plt.title('Simple Scatter Plot')
plt.legend()
plt.show()
散布図 (2)
オブジェクト指向スタイルは省略します。
バブルチャートは、対となるデータに加えて、それに関係するもう一つのデータの量を円の大きさで表したグラフです。Matplotlib の場合、関数 scatter() を使用し、属性 s にデータのサイズを渡すことで、プロットする点の大きさが変化するグラフになります。属性 markersize (ms) を使うとエラーになるので注意してください。
リスト : バブルチャート (1)
import matplotlib.pyplot as plt
import numpy as np
x = [128, 139.4, 129.7, 129.7, 127.9, 127.2, 144.1, 130.4, 140.4]
y = [26.2, 37, 29.6, 29.6, 26.3, 26.9, 42.5, 28.7, 39.5]
z = [14, 11, 8, 9, 17, 19, 22, 26, 12]
plt.scatter(x, y, s = [n * 25 for n in z], alpha = 0.7, label = "data1")
plt.xlim(126, 146)
plt.ylim(24, 44)
plt.title('Bubble Chart')
plt.legend()
plt.show()
リスト : バブルチャート (オブジェクト指向スタイル)
import matplotlib.pyplot as plt
import numpy as np
x = [128, 139.4, 129.7, 129.7, 127.9, 127.2, 144.1, 130.4, 140.4]
y = [26.2, 37, 29.6, 29.6, 26.3, 26.9, 42.5, 28.7, 39.5]
z = [14, 11, 8, 9, 17, 19, 22, 26, 12]
fig, ax = plt.subplots()
ax.scatter(x, y, s = [n * 25 for n in z], alpha = 0.7, label = "data1")
ax.set_xlim(126, 146)
ax.set_ylim(24, 44)
ax.set_title('Bubble Chart')
ax.legend()
plt.show()
バブルチャート (1)
リスト : バブルチャート (2)
import matplotlib.pyplot as plt
import numpy as np
x = [10, 20, 30, 40, 50, 60]
y1 = [15.6, 15.0, 15.8, 16.1, 16.9, 16.9]
z1 = [4, 8, 16, 12, 10, 20]
y2 = [16.9, 16.5, 16.3, 17.1, 16.6, 16.4]
z2 = [20, 10, 12, 16, 8, 4]
plt.scatter(x, y1, s = [n * 25 for n in z1], alpha = 0.5, label = "data1")
plt.scatter(x, y2, s = [n * 25 for n in z2], alpha = 0.5, label = "data2")
plt.ylim(14, 18)
plt.title('Bubble Chart')
plt.legend()
plt.show()
バブルチャート (2)
オブジェクト指向スタイルは省略します。
Matplotlib を使用した時系列チャートの作成は、標準ライブラリ datetime (または Pandas の Timestamp) を組み合わせて時間を定義するのが一般的です。基本的には、グラフを描画する関数に datetime のデータを渡すだけで簡単に行えます。それでは簡単な例題として、東京の年平均気温を散布図で表してみましょう。データは「気象庁: 年ごとの値 (東京)」の 1975 年から 2021 年までの年平均気温を用いました。
| 1975 | 1976 | 1977 | 1978 | 1979 | 1980 | 1981 | 1982 |
|---|---|---|---|---|---|---|---|
| 15.6 | 15.0 | 15.8 | 16.1 | 16.9 | 15.4 | 15.0 | 16.0 |
| 1983 | 1984 | 1985 | 1986 | 1987 | 1988 | 1989 | 1990 |
| 15.7 | 14.9 | 15.7 | 15.2 | 16.3 | 15.4 | 16.4 | 17.0 |
| 1991 | 1992 | 1993 | 1994 | 1995 | 1996 | 1997 | 1998 |
| 16.4 | 16.0 | 15.5 | 15.9 | 16.3 | 15.8 | 16.7 | 16.7 |
| 1999 | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 | 2006 |
| 17.0 | 16.9 | 16.5 | 16.7 | 16.0 | 17.3 | 16.2 | 16.4 |
| 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 |
| 17.0 | 16.4 | 16.7 | 16.9 | 16.5 | 16.3 | 17.1 | 16.6 |
| 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | |
| 16.4 | 16.4 | 15.8 | 16.8 | 16.5 | 16.5 | 16.6 |
このように、一定の時間経過によって計測されたデータ列のことを「時系列 (time series)」といいます。
リスト : 時系列チャート
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime
x = [datetime(n, 1, 1) for n in range(1975, 2022)]
y = [
15.6, 15.0, 15.8, 16.1, 16.9, 15.4, 15.0, 16.0, 15.7, 14.9,
15.7, 15.2, 16.3, 15.4, 16.4, 17.0, 16.4, 16.0, 15.5, 16.9,
16.3, 15.8, 16.7, 16.7, 17.0, 16.9, 16.5, 16.7, 16.0, 17.3,
16.2, 16.4, 17.0, 16.4, 16.7, 16.9, 16.5, 16.3, 17.1, 16.6,
16.4, 16.4, 15.8, 16.8, 16.5, 16.5, 16.6
]
plt.scatter(x, y, label='Celsius')
plt.ylim(14, 18)
plt.title('Annual Average Temperature in Tokyo')
plt.legend()
plt.show()
リスト : 時系列チャート (オブジェクト指向スタイル)
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime
x = [datetime(n, 1, 1) for n in range(1975, 2022)]
y = [
15.6, 15.0, 15.8, 16.1, 16.9, 15.4, 15.0, 16.0, 15.7, 14.9,
15.7, 15.2, 16.3, 15.4, 16.4, 17.0, 16.4, 16.0, 15.5, 16.9,
16.3, 15.8, 16.7, 16.7, 17.0, 16.9, 16.5, 16.7, 16.0, 17.3,
16.2, 16.4, 17.0, 16.4, 16.7, 16.9, 16.5, 16.3, 17.1, 16.6,
16.4, 16.4, 15.8, 16.8, 16.5, 16.5, 16.6
]
fig, ax = plt.subplots()
ax.scatter(x, y, label='Celsius')
ax.set_ylim(14, 18)
ax.set_title('Annual Average Temperature in Tokyo')
ax.legend()
plt.show()
時系列チャート (1)
リスト : 時系列チャート (2)
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime
# 月平均気温
ys1 = [7.1, 8.0, 9.6, 17.1, 20.0, 23.1, 28.7, 29.0, 26.6, 20.6, 13.7, 8.1]
# 月平均最高気温
ys2 = [11.8, 12.5, 14.8, 21.8, 24.8, 27.7, 33.5, 33.6, 30.9, 24.5, 17.8, 13.2]
# 月平均最低気温
ys3 = [2.9, 4.1, 5.1, 13.1, 15.6, 19.3, 25.0, 25.7, 23.5, 17.4, 10.2, 3.8]
# 月
x = [datetime(2024, n, 1) for n in range(1, 13)]
# 描画
plt.plot(x, ys1, lw=2, marker = 'o', label = "avg")
plt.plot(x, ys2, lw=2, marker = 'o', label = "max")
plt.plot(x, ys3, lw=2, marker = 'o', label = "min")
plt.ylim(0, 40)
plt.title('Average temperature in 2024')
plt.xlabel('Month')
plt.ylabel('Celsius')
plt.legend()
plt.show()
オブジェクト指向スタイルは省略します。
時系列チャート (2)
2 つの確率変数の間に相関が認められるとき、その関係を曲線や曲面で代表することを「回帰 (regression)」といいます。相関に線形傾向が見られる場合、その関係を一本の直線で表すことができます。これを「直線回帰」とか「線形回帰」といい、その直線を「回帰直線」といいます。詳しい説明は拙作のページをお読みください。
簡単な例題として、東京の年平均気温が今後どの程度上昇するか、回帰を用いて推定してみましょう。回帰直線は NumPy の関数 polyfit() を使うと簡単に求めることができます。
回帰直線を y = ax + b とすると、polyfit() は (a, b) を返します。計算結果は次のようになりました。
a = 0.024606845513413408 b = -32.904902867714874
あとは plot() で散布図上に回帰直線を引くだけです。
リスト : 回帰直線
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime
x = [datetime(n, 1, 1) for n in range(1975, 2022)]
y = [
15.6, 15.0, 15.8, 16.1, 16.9, 15.4, 15.0, 16.0, 15.7, 14.9,
15.7, 15.2, 16.3, 15.4, 16.4, 17.0, 16.4, 16.0, 15.5, 16.9,
16.3, 15.8, 16.7, 16.7, 17.0, 16.9, 16.5, 16.7, 16.0, 17.3,
16.2, 16.4, 17.0, 16.4, 16.7, 16.9, 16.5, 16.3, 17.1, 16.6,
16.4, 16.4, 15.8, 16.8, 16.5, 16.5, 16.6
]
# 回帰直線 y = a * x + b
a, b = np.polyfit(range(1975, 2022), y, 1)
print('a = ', a, 'b = ', b)
plt.scatter(x, y, label='Celsius')
plt.plot([datetime(1975, 1, 1), datetime(2030, 1, 1)],
[a * 1975 + b, a * 2030 + b],
lw = 4, color = 'pink', label = 'regression')
plt.ylim(14, 18)
plt.title('Annual Average Temperature in Tokyo')
plt.legend()
plt.show()
リスト : 回帰直線 (オブジェクト指向スタイル)
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime
x = [datetime(n, 1, 1) for n in range(1975, 2022)]
y = [
15.6, 15.0, 15.8, 16.1, 16.9, 15.4, 15.0, 16.0, 15.7, 14.9,
15.7, 15.2, 16.3, 15.4, 16.4, 17.0, 16.4, 16.0, 15.5, 16.9,
16.3, 15.8, 16.7, 16.7, 17.0, 16.9, 16.5, 16.7, 16.0, 17.3,
16.2, 16.4, 17.0, 16.4, 16.7, 16.9, 16.5, 16.3, 17.1, 16.6,
16.4, 16.4, 15.8, 16.8, 16.5, 16.5, 16.6
]
# 回帰直線 y = a * x + b
a, b = np.polyfit(range(1975, 2022), y, 1)
print('a = ', a, 'b = ', b)
fig, ax = plt.subplots()
ax.scatter(x, y, label='Celsius')
ax.plot([datetime(1975, 1, 1), datetime(2030, 1, 1)],
[a * 1975 + b, a * 2030 + b],
lw = 4, color = 'pink', label = 'regression')
ax.set_ylim(14, 18)
ax.set_title('Annual Average Temperature in Tokyo')
ax.legend()
plt.show()
回帰直線
グラフの一方の軸が対数スケールになっているグラフを「片対数グラフ (Semi-log graph)」といい、両方の軸が対数スケールになっているグラフを「両対数グラフ (Log-log graph)」といいます。Matplotlib で対数グラフを描画する方法は簡単です。x, y 軸のスケールを設定する関数 plt.xscale(), plt.yscale() に 'log' を指定するだけです。oo-style の場合はメソッド ax.set_xscale(), ax.set_yscale() を使います。
リスト : 片対数グラフ
import matplotlib.pyplot as plt
import numpy as np
x = [0, 1, 2, 3, 4]
y = [10 ** n for n in x]
# y軸を対数スケールにする
plt.yscale('log')
plt.grid(True, which="both", linestyle="--")
plt.plot(x, y, label='10 ** x')
plt.title('Semi-log Plot (y-axis)')
plt.legend()
plt.show()
リスト : 片対数グラフ (オブジェクト指向スタイル)
import matplotlib.pyplot as plt
import numpy as np
x = [0, 1, 2, 3, 4]
y = [10 ** n for n in x]
fig, ax = plt.subplots()
# y軸を対数スケールにする
ax.set_yscale('log')
ax.grid(True, which="both", linestyle="--")
ax.plot(x, y, label='10 ** x')
ax.set_title('Semi-log Plot (y-axis)')
ax.legend()
plt.show()
片対数グラフ
次は度数分布表を円グラフで描画してみましょう。
リスト : 円グラフ
import matplotlib.pyplot as plt
import numpy as np
ls = ['130-135', '135-140', '140-145', '145-150', '150-155', '155-160', '160-165', '165-170']
vs = [1, 6, 12, 25, 32, 17, 6, 1]
plt.pie(vs, labels = ls, wedgeprops={'edgecolor': 'white'})
plt.title('Pie Chart')
# plt.legend(loc='best')
plt.show()
リスト : 円グラフ (オブジェクト指向スタイル)
import matplotlib.pyplot as plt
import numpy as np
ls = ['130-135', '135-140', '140-145', '145-150', '150-155', '155-160', '160-165', '165-170']
vs = [1, 6, 12, 25, 32, 17, 6, 1]
fig, ax = plt.subplots()
ax.pie(vs, labels = ls, wedgeprops={'edgecolor': 'white'})
ax.set_title('Pie Chart')
# plt.legend(loc='best')
plt.show()
円グラフ
ドーナツグラフ (width = 0.5)
Matplotlib を使用して極座標グラフ (Polar Plot) を描く場合、関数 plt.polor() を直接呼び出す方法が簡単です。
plt.polar(theta, r)
plt.polor() の第 1 引数に角度、第 2 引数に半径を渡します。角度はラジアンで指定します。半径と角度の目盛りは次の関数で指定します。
簡単な実行例を示します。
リスト : カーディオイド
import numpy as np
import matplotlib.pyplot as plt
# データの作成 (0から360度までをラジアンに変換)
theta = np.linspace(0, 2 * np.pi, 100)
r = 1 + np.sin(theta) # カーディオイド(心臓形)の数式
# 極座標のサブプロットを作成
plt.polar(theta, r)
plt.rgrids([0.0, 0.5, 1.0, 1.5, 2.0]) # 半径の目盛り線
plt.title('cardioid')
plt.show()
カーディオイド
リスト : アルキメデスの螺旋
import numpy as np
import matplotlib.pyplot as plt
theta = np.linspace(0, 8 * np.pi, 500) # 角度
r = 0.5 * theta
plt.polar(theta, r)
plt.title('Archimedean spiral')
plt.show()
アルキメデスの螺旋
oo-style で極座標のグラフを描画するには、サブプロットを作成する際に projection='polar' を指定します。
fig = plt.figure()
ax = fig.add_subplot(projection='polar')
または
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
描画関数は polar() ではなく、plot() になることに注意してください。このほかにも、bar() や scatter() なども使用することができます。
ax.plot(theta, r)
第 1 引数に角度、第 2 引数に半径を渡します。角度はラジアンで指定します。便利なメソッドを以下に示します。
oo-style のプログラムを以下に示します。
リスト : カーディオイド (オブジェクト指向スタイル)
import numpy as np
import matplotlib.pyplot as plt
# データの作成 (0から360度までをラジアンに変換)
theta = np.linspace(0, 2 * np.pi, 100)
r = 1 + np.sin(theta) # カーディオイド(心臓形)の数式
# 極座標のサブプロットを作成
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
ax.plot(theta, r)
ax.set_rticks([0.0, 0.5, 1.0, 1.5, 2.0]) # 半径の目盛り線
ax.set_title('cardioid')
plt.show()
リスト : アルキメデスの螺旋 (オブジェクト指向スタイル)
import numpy as np
import matplotlib.pyplot as plt
theta = np.linspace(0, 8 * np.pi, 500) # 角度
r = 0.5 * theta
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
ax.plot(theta, r)
ax.set_title('Archimedean spiral')
plt.show()
極座標の散布図を描画するには、ax.scatter(theta, r) を使用します。通常の scatter(x, y) とは異なり、第 1 引数に角度 θ (ラジアン表記)、第 2 引数に半径 r を渡す点に注意してください。
リスト : 極座標の散布図
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
N = 500
r = np.random.randn(N)
theta = 2 * np.pi * np.random.rand(N)
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
ax.scatter(theta, r, alpha=0.5)
ax.set_title('Polar Scatter')
plt.show()
極座標の散布図
Matplotlib は極座標と棒グラフを組み合わせることで、「鶏頭図 (polar area diagram または Nightingale rose diagram)」を描画することができます。鶏頭図は「扇形の角度」ではなく、「扇形の半径 (または面積)」でデータの大きさを表現するため、通常の円グラフではなく、極座標上の棒グラフとして実装します。
リスト : 鶏頭図
import numpy as np
import matplotlib.pyplot as plt
# 月
months = range(1, 13)
# 令和7年度東京都交通事故死者数
values = [234, 189, 191, 196, 172, 179, 185, 203, 229, 227, 252, 290]
# 360度(2*pi)をデータの数(12)で等分割する
n_data = len(values)
angles = np.linspace(0, 2 * np.pi, n_data, endpoint=False)
colors = ['blue', 'orange', 'green', 'red'] * 3
# 扇形が重ならないよう、1 つあたりの幅(Width)を設定
width = 2 * np.pi / n_data
# グラフの描画
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
ax.set_theta_zero_location('N') # 開始位置を上 (北) に設定
ax.set_theta_direction(-1) # 時計回りに配置変更
# 棒グラフ(ax.bar)を極座標にプロット
ax.bar(angles, values, width=width, color=colors, edgecolor='white', linewidth=1.5)
ax.set_xticks(angles)
ax.set_xticklabels(months)
ax.set_title("Polar area diagram")
plt.show()
鶏頭図