プロジェクト

全般

プロフィール

Python Matplotlib

はじめに

Pythonでグラフをプロットするライブラリの定番です。MATLABのグラフプロットに近い使い勝手を提供する pyplot API と、オブジェクト指向APIと2つのAPI体系が用意されています。

準備

インストール

pip install matplotlib でインストールします。

日本語化させる

matplotlibは日本語対応していないので、グラフの軸名などに日本語が設定できません。
  1. 日本語を使えるようにするライブラリを追加で取り込みます。
  2. 日本語フォントを設定

matplotlib_fontja

python 3.12以降にも利用できる matplotlibの日本語対応ライブラリです。pipでインストール可能です。
https://github.com/ciffelia/matplotlib-fontja

japanize_matplotlibライブラリのインストール

書籍、ブログ等ではまずこれが出てくるほどメジャーですが、2025年6月時点の最新バージョン 1.1.3(2020年10月リリース)では、Python 3.12以降でエラーとなってしまいます。Python 3.12においてdistutilsライブラリが標準から除外されたため、japanize_matplotlibの中で使用しているdistutilsが名前未解決になるためです。

日本語フォントを設定

次のいずれかを実施

  • システムに日本語フォントを入れた上で、plt.rcParamsを更新
  • matplotlib.font_managerにフォントパスを登録
rcParamsの例

macOSでは、"Hiragino Sans" や ”Osaka” などを指定します。
plt.rcParams["font.family"] = "Osaka"

Windows OSでは、"Meiryo" や "MS Gothic" などを指定します。

プロットの構成

classDiagram Figure *-- Axes Axes *-- Axis

Figureは、グラフプロット領域全体を表すクラスで、グラフプロット Axes を保持します。保持する個数は複数が可能です。
Axesは、X軸、Y軸としてAxisを保持します。

プログラミングメモ

ライブラリのインポート

import matplotlib.pyplot as plt

pyplotモジュールをインポートします。慣例で、名前をpltで参照しています。

APIのアプローチ2種類

Matplotlib で混乱する要因が、次の2種類のAPIの存在です。

  1. MATLABスタイルAPI
    plt.xxx で全部済ませる
  2. オブジェクト指向API
    axを使う

MATLABスタイルAPI

matplotlib.pyplotモジュール に定義される関数を逐次呼び出してグラフを描かせます。
基本的なグラフのプロットが可能ですが、細かく設定するには次のオブジェクト指向APIを使用します。

MATLABスタイルAPIで記述していて、一部オブジェクト指向APIを使わざるを得ない設定をする場合は、

  • plt.gcf().xxx() でFigureオブジェクトのメソッド呼び出し
  • plt.gca().xxx() でAxesオブジェクトのmethod呼び出し

としてアクセスが可能です。

オブジェクト指向API

Figure、Axesなどのオブジェクトとその属性・メソッドを呼び出すことで、グラフの描画領域、個別のグラフなどを細かく設定してグラフをプロットします。

最初の一歩

sin関数のグラフ描画

まずは最小限のコードで三角関数 sin のグラフを描画します。

描画 コード
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-2 * np.pi, 2 * np.pi, 1_000)
y = np.sin(x)

plt.plot(x, y)
plt.show()

グラフの題名、X軸およびY軸の軸名、グリッド線を表示します。

描画 コード
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-2 * np.pi, 2 * np.pi, 1_000)
y = np.sin(x)

plt.title("sine function")
plt.xlabel("radian")
plt.ylabel("value")
plt.grid()

plt.plot(x, y)
plt.show()

グラフの配置、図の大きさ

描画したグラフの画像サイズ

matplotlibは、プロットしたグラフを画像として生成します。その画像サイズを指定するには、次のように

fig = plt.figure(figsize=(16, 4.5))

ここで、figsizeパラメータに指定するのは画像サイズの幅、高さのタプルで単位はインチになります。インチと画素数の対応はデフォルトでは100dpiです。このfigure関数の実行は省略可能で、その時はデフォルトの画像サイズとなります。

複数のグラフを配置するときのグラフ間の余白

1つの画像に複数のグラフを並べるときの、グラフとグラフの縦・横の間隔を設定します。

fig.subplots_adjust(hspace=0.4, wspace=0.2) 

水平方向の間隔をwspaceパラメータで、垂直方向の間隔をhspaceパラメータで指定します。どうやらwはwidth、hはheightの略のようです。

図にグラフを追加

ax1 = fig.add_subplot(131)
ax2 = fig.add_subplot(132)

figureに対してadd_subplotでグラフ領域を追加します。引数は、1桁の数字を3つつなげて3桁の整数を渡します。1桁目が縦方向の分割数(1は分割なし)、2桁目が横方向の分割数(1は分割なし)、3桁目は左上から何番目のグラフ領域かを指定します。その位置のグラフのAxesオブジェクトが返されます。
この例では縦は1行、横は3列にグラフ領域を配置し、左から1番目、2番目のグラフ領域のAxesを取得しています。

ラベル

タイトル

グラフの上部中央に表示する題名になるラベルです。

matplot API

グラフは一つなので、グラフ上部のタイトルを 別名pltモジュールの関数で設定します。

plt.title('memory plot')

オブジェクト指向API

図の中に複数のグラフを配置できるので、個々のグラフ(Axes)にタイトルを設定します。

ax3.set_title('cpu load')

軸ラベル

matplot API

plt.xlabel('time')
plt.ylabel('memory[KiB]')

オブジェクト指向API

ax2.set_xlabel('time')
ax2.set_ylabel('load')

グリッド表示

目盛の線の表示

matplot API

plt.grid()

軸線(Major)を表示 plt.grid() 軸線(MajorとMinor)を表示、Minorは破線を指定。コード例は後述
    plt.minorticks_on()
    plt.grid(which="major")
    plt.grid(which="minor", linestyle=":")
オブジェクト指向API

書式
Axes.grid(b=None, which="major", axis="both", **kwargs)

  • bには、True | False | None のいずれかを指定。True:グリッド表示、False:グリッド非表示、None:現在の状態を反転
  • whichには、major | minor | both のいずれかを指定。major:majorメモリに線を引く、minorメモリに線を引く、both:両方に線を引く
  • axisには、x | y | both のいずれかを指定。x:X軸の値に線を引く(縦線)、y:Y軸の値に線を引く(横線)、both:両方に線を引く

軸の目盛りの数値

数値の範囲を指定

デフォルトでは、表示したいデータの範囲に応じて軸の目盛りの範囲が決まります。
目盛りの範囲を指定するには、次のように設定します。

import matplotlib.pyplot as plt
import numpy as np

NUM_POINTS = 1_000
MEAN_LEVEL = -90.0
STD_DEV = 3.0
rng = np.random.default_rng()

frequencies = np.linspace(2500e+6, 2540e+6, NUM_POINTS)
noise_floor = rng.normal(MEAN_LEVEL, STD_DEV, NUM_POINTS)

plt.grid()
plt.plot(frequencies, noise_floor)
plt.show()
次のコードを上のコードに追加
plt.ylim(-120, -40)

上側のプロットは、Y軸の範囲がデータの範囲に応じて自動的に設定されたものです。
下側のプロットは、Y軸の範囲を -120から-40の範囲に設定したものです。

X軸についても、plt.xlim(2500e+6, 2540e+6) と明示的に設定することができます。

数値の単位をK, Mなどに

デフォルトでは、数値が科学記数法で表示されます。前項のノイズフロアのプロットでは、X軸の目盛りが、値 2,500,000,000 において、2.500 と表記され、X軸の右端に 1e9 と指数が表記されています。

これを、KやMなどの 10 n の数値で表示します。

import matplotlib.ticker as ticker
 :
plt.gca().xaxis.set_major_formatter(ticker.FuncFormatter(
    lambda x, pos: f"{x/1e6: .0f}" 
))

数値を一定間隔の刻み幅で

前項のサンプルでは、Y軸の目盛りが10刻みで表記されました。これを5刻みにするとします。

plt.gca().yaxis.set_major_locator(ticker.MultipleLocator(5))

または、あらかじめ目盛りに表示する数値の列を設定します。

plt.yticks(np.arange(-120, -35, 5))

日時

時系列データで、軸の表示を日時にする場合、文字列ではなく datetime型で渡す必要があります。

日時の軸の表示設定

日時は文字数が多いので、デフォルトの軸の値の表示は重なり合ってしまうので、軸の値の表示を回転させる等のテクニックが必要になります。

デフォルトの表示
30度回転 plt.xticks(rotation=30)
30度回転と書式をHH:MMに指定
  • 日時の軸の表現形式を変更
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
  :
plt.xticks(rotation=30)
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%H:%M"))

折れ線プロットの表現

折れ線は、線の種類、データ(頂点)のマーカー形状、色を指定することができます。
それぞれplot関数のパラメータで個別に指定する方法と、fmtパラメータで1つの文字列でまとめて指定する方法があります。

markerパラメータでマーカー種類を指定

plt.plot(x, y, marker='.')
マーカーの形状に、中くらいの大きさの丸を指定。指定する文字とマーカー種類は次(抜粋)

o ●、^ ▲、v ▼、< ◀︎、> ▶︎、s ■、+ +、x ×、D ◆ など

linestyleパラメータ(ls)で線種を指定

plt.plot(x, y, linestyle='--')
plt.plot(x, y, ls=':')

- 実線、-- 破線、: 点線、-. 一点破線

colorパラメータ(c)で色を指定

plt.plot(x, y, color='r')
plt.plot(x, y, c='green')

色の指定は、名前(名前の略字)、16進指定、RGBの10進指定などが可能です。
b blue 青, g green 緑, r red 赤、c cyan 水色、m magenta 紫、y yellow 黄色、k black 黒、w white 白
#ff0000
[0.1, 0.8, 0.0]
matplotlibで使用可能な名前付きカラー

fmtパラメータでマーカー・線種・色を一括指定

plt.plot(x, y, 'o:g')
マーカー種類を大きな円('o')、線種を点線(':')、色を緑('g')と指定しています。

複数のグラフを1枚の画像にプロット

subplotを使って、複数のグラフを1つの画像にプロットします。グラフの縦・横・プロット対象インデックスを指定すると、そのグラフにプロットされます。

縦に2つ、横に3つのグラフを一つの画像にプロットし、その4つ目(2行目1桁目)にプロット開始する
plt.subplot(2, 3, 4)

画像全体のラベルは、plt.suptitle('Whole Title')

一つのグラフに複数のプロット

2つのプロットと凡例表示

2つのプロットを実行します。

plt.plot(xarray, y1array, color='black', label='cpu')  # 1つ目のプロット、黒色で、凡例を'cpu'
plt.plot(xarray, y2array, color='blue', label='memory')  # 2つ目のプロット、青色で、凡例を'memory'
plt.legend(loc='upper right')  # 凡例を、右上に表示

同じグラフに複数のデータ系列を重ねて表示するので、色を分けると便利です。plot()関数の引数 color で色をそれぞれ指定しています。
次に凡例を表示するため、plot()関数の引数 label で名前を指定し、legend()関数の引数 loc で凡例の表示位置を指定します。

アニメーション

プロットを時間とともに変化させることでアニメーションのような効果を持たせます。
matplotlib では、2つの方法が用意されています。
1つは、あらかじめアニメーションのフレーム毎のプロットデータをリストとして作成しておき、リストの各要素であるプロットデータを一定間隔でプロットする方法です。
2つ目は、アニメーション実行中にリアルタイムにプロットデータを生成する方法です。

ArtistAnimation

figure オブジェクトとプロットオブジェクトのリストを必須のパラメータとしてArtistAnimationオブジェクトを生成します。
オプションのパラメータは、フレーム間隔(デフォルト200ms)、繰り返し有無、繰り返し時の待ち時間、描画最適化があります。

円周上を移動する点のプロット

サンプルコードとして、円周上を移動する点をアニメーション表示します。

import matplotlib.pyplot as plt
import matplotlib.animation as animation # アニメーション機能のパッケージをインポート
import numpy as np

frames = [] # アニメーションのためにプロットオブジェクトを格納するリスト
for theta in np.linspace(0, 2 * np.pi, 100): # アニメーションの各フレーム毎にイテレート
    x = np.cos(theta)
    y = np.sin(theta)
    frame = plt.plot(x, y, 'o', color='blue') # plot結果のプロットオブジェクトを取得
    frames.append(frame) # プロットオブジェクトをリストに追加

ani = animation.ArtistAnimation(plt.gcf(), frames) # アニメーションを生成
plt.show()

実行結果

IntelliJ (PyCharm)上で実行

IntelliJ IDEAでは、Matplotlibのグラフ表示をするプログラムを実行するとプロット結果の画像がIDE内に表示されます。
しかし、アニメーションの表示ができないので、次のコードを追加します。

matplotlib.use('TkAgg')

別ウィンドウにMatplotlibのグラフが表示され、アニメーションも実行されます。
コードから、tkを使っていることがわかりますが、python-tkがインストールされている必要があります。


約1ヶ月前に更新