キャンバスしたい(matplotlib.pyplot.subplots

 1import matplotlib.pyplot as plt
 2
 3# キャンバスを作成
 4fig, ax = plt.subplots()
 5
 6sc1 = ax.scatter(x=xdata, y=ydata)
 7sc2 = ax.scatter(x=xdata, y=ydata2)
 8
 9# グラフのタイトルと軸ラベルを設定
10ax.set_title("散布図の例")
11ax.set_xlabel("X軸")
12ax.set_ylabel("Y軸")
13
14# 凡例を追加
15ax.legend(
16    [sc1, sc2],    # 凡例の対象
17    ["データ1", "データ2"]  # 凡例のラベル
18)
19
20# キャンバスを保存
21fig.savefig("scatter.png")
22
23# グラフを表示
24plt.show()

pyplot.subplotsでキャンバスを作成できます。 返り値はFigureオブジェクトとAxesオブジェクトです。 Axesオブジェクトを使ってグラフを描画します。

1# MATLAB-style
2plt.figure(figsize=(6, 4))
3plt.scatter(x=xdata, y=ydata)
4plt.title("散布図の例")
5plt.xlabel("X軸")
6plt.ylabel("Y軸")
7plt.savefig("scatter.png")
8plt.show()

キャンバスサイズしたい(figsize

1fig, ax = plt.subplots(
2    figsize=(8, 6)  # 幅8インチ、高さ6インチのキャンバスを作成
3)

figsizeオプションで、キャンバスのサイズをインチ単位で指定できます。

複数に分割したい(nrows / ncols

1import matplotlib.pyplot as plt
2
3fig, axs = plt.subplots(
4    figsize=(8, 12),
5    nrows=2,
6    ncols=3,
7    # squeezed=False,  # 2行3列のキャンバスを作成
8)

nrowsncolsオプションで、キャンバスを複数に分割できます。 このときのaxsは、行数(nrows)と列数(ncols)の 2次元配列(ndarray)になっています。

注意

nrows=1またはncols=1のとき、axsは1次元配列になります。 squeezed=Falseオプションで分割数が1のときも2次元配列になります。 後述するループ処理では、分割数に依存しないように、squeezed=Falseを指定することをオススメします。

ループ処理したい(ravel

 1# データを準備する
 2# 次のカラムを持つpd.DataFrameを想定
 3# time | v1 | v2 | v3 | v4 | v5 | v6
 4data = pd.DataFrame(...)
 5
 6# キャンバスを分割
 7# fig: matplotlib.figure.Figure
 8# axs: np.ndarray[matplotlib.axes.Axes]
 9fig, axs = plt.subplots(
10    nrows=2,
11    ncols=3,
12    figsize=(8, 12),
13    squeezed=False,
14)
15
16# 2次元配列のキャンバスを1次元配列に変換
17canvas = axs.ravel()
18
19# 反復処理でグラフを描く
20for i, ax in enumerate(canvas):
21    data.plot.scatter(
22        x="time",
23        y=f"v{i+1}",
24        ax=ax
25    )
26
27# キャンバスを保存
28fig.savefig("waveforms.png")

複数のグラフをループ処理で描くサンプルです。 分割したキャンバスの戻り値は2次元配列(np.ndarray[matplotlib.axes.Axes])になっています。 squeeze=Falseオプションを指定し、分割数に依らず2次元配列に変換しています。

2次元配列のままでもループ処理できますが、ravelnp.ndarray.ravelメソッド)で1次元配列に変換しておくと、アクセスが楽になります。 上のサンプルでは、pandasの散布図と組み合わせたものにしてみました。

注釈

同様のことはflattennp.ndarray.flattenメソッド)でもできます。

1# iterator: ループ処理の中でアクセスできる
2for i, ax in enumerate(axs.flatten()):
3    data.plot.scatter(
4        x="time",
5        y=f"v{i+1}",
6        ax=ax
7    )

flattenはイテレーターを返すので、 canvas = axs.ravel()canvas = axs.flatten() に置き換えただけではループ処理でアクセスできません。 ものすごい大量のグラフを描く時はflattenの方がメモリ効率がよいかもしれません。 通常はravelで十分です。

リファレンス