STEP 9:subplotと複数グラフの配置

📐 STEP 9: subplotと複数グラフの配置

1つの図に複数のグラフを美しく配置する方法をマスターしよう!

📋 このステップで学ぶこと

  • subplotの概念とFigure/Axesの関係
  • plt.subplot()の使い方(1つずつ作成)
  • plt.subplots()の使い方(推奨される方法)
  • グリッドレイアウト(2×2、3×2など)
  • 図全体のサイズと余白の調整
  • 実践的なダッシュボード風レイアウト

📊 1. subplotとは何か

subplotの概念

subplot(サブプロット)とは、1つの図(Figure)の中に複数のグラフ(Axes)を配置する機能です。

これまでのステップでは、1つの図に1つのグラフを描いてきました。しかし、実際のデータ分析では、複数のグラフを並べて比較したい場面がよくあります。例えば、売上、利益、来客数を同時に表示したり、同じデータを異なる視点(折れ線グラフとヒストグラム)で見せたりする場合です。

subplotを使えば、これらを1つの図にまとめて表示できます。

💡 subplotの活用場面

日常のレポート作成で、こんな場面はありませんか?

「売上」「利益」「来客数」を1ページにまとめたい
→ 3つのグラフを横に並べて表示

同じデータを「折れ線」と「棒グラフ」で比較したい
→ 2つのグラフを左右に配置

ダッシュボード風の画面を作りたい
→ 2×2のグリッドに4つのグラフを配置

FigureとAxesの関係

subplotを理解するには、まずFigureAxesの関係を知ることが大切です。

Figure(フィギュア)は、グラフ全体を含む「キャンバス」のようなものです。画用紙をイメージしてください。

Axes(アクセス)は、Figure上に描かれる「個々のグラフ」です。画用紙の上に貼る写真や絵のようなものです。

【概念図】Figure と Axes の関係 Figure(図全体 = キャンバス・画用紙) ┌─────────────────────────────────────┐ │ │ │ ┌───────────┐ ┌───────────┐ │ │ │ │ │ │ │ │ │ Axes 1 │ │ Axes 2 │ │ │ │ (グラフ1) │ │ (グラフ2) │ │ │ │ │ │ │ │ │ └───────────┘ └───────────┘ │ │ │ │ ┌───────────┐ ┌───────────┐ │ │ │ │ │ │ │ │ │ Axes 3 │ │ Axes 4 │ │ │ │ (グラフ3) │ │ (グラフ4) │ │ │ │ │ │ │ │ │ └───────────┘ └───────────┘ │ │ │ └─────────────────────────────────────┘ ・Figure = キャンバス(画用紙)1枚 ・Axes = グラフ1つ1つ(上の例では4つ) ・subplot = Axes を配置する機能
📌 重要な用語のまとめ
用語 意味 たとえ
Figure グラフ全体を含む図 画用紙、キャンバス
Axes 個々のグラフ領域 画用紙に貼る写真
subplot 複数のAxesを配置する機能 写真を並べるレイアウト

🔢 2. plt.subplot()の使い方(1つずつ作成)

plt.subplot()とは

plt.subplot()は、グラフを1つずつ順番に作成する方法です。「今からこの位置にグラフを描きます」と宣言してから描画します。

基本的な書き方

plt.subplot()には3つの数字を指定します。

【plt.subplot() の書き方】 plt.subplot(行数, 列数, 位置) ・行数:グリッドを何行にするか ・列数:グリッドを何列にするか ・位置:左上から数えて何番目か(1から開始) 【例】plt.subplot(1, 2, 1) → 1行2列のグリッドの「1番目」(左側) 【例】plt.subplot(2, 3, 5) → 2行3列のグリッドの「5番目」 グリッドの番号の数え方: ┌───┬───┬───┐ │ 1 │ 2 │ 3 │ ← 上の行は左から 1, 2, 3 ├───┼───┼───┤ │ 4 │ 5 │ 6 │ ← 下の行は左から 4, 5, 6 └───┴───┴───┘

1行2列のグラフを作成する

まず、最もシンプルな例として、左右に2つのグラフを並べる方法を見てみましょう。

コードを段階的に解説します。

📝 ステップ1: ライブラリとデータの準備

まず、Matplotlibをインポートし、グラフに使うデータを用意します。

import matplotlib.pyplot as plt # グラフに使うデータを用意 x = [1, 2, 3, 4, 5] # X軸の値(共通) y1 = [2, 4, 6, 8, 10] # グラフ1用のデータ y2 = [1, 3, 5, 7, 9] # グラフ2用のデータ
📝 ステップ2: Figureを作成してサイズを指定

plt.figure()で「キャンバス」を作成します。figsize=(幅, 高さ)でサイズを指定します(単位はインチ)。

# Figure(キャンバス)を作成 # figsize=(12, 5) は 横12インチ × 縦5インチ の意味 plt.figure(figsize=(12, 5))
📝 ステップ3: 左側のグラフを描く

plt.subplot(1, 2, 1)で「1行2列の1番目(左側)」を選択し、その後にグラフを描きます。

# 左側のグラフ(1行2列の1番目) plt.subplot(1, 2, 1) # ここから1番目のグラフ領域に描画 # 折れ線グラフを描く plt.plot(x, y1, marker=’o’, color=’steelblue’) # タイトル・軸ラベル・グリッドを設定 plt.title(“グラフ1: 直線的な増加”, fontsize=14, fontweight=’bold’) plt.xlabel(“X軸”) plt.ylabel(“Y軸”) plt.grid(True, alpha=0.3)
📝 ステップ4: 右側のグラフを描く

plt.subplot(1, 2, 2)で「1行2列の2番目(右側)」を選択し、同様にグラフを描きます。

# 右側のグラフ(1行2列の2番目) plt.subplot(1, 2, 2) # ここから2番目のグラフ領域に描画 # 折れ線グラフを描く plt.plot(x, y2, marker=’s’, color=’coral’) # タイトル・軸ラベル・グリッドを設定 plt.title(“グラフ2: 奇数の増加”, fontsize=14, fontweight=’bold’) plt.xlabel(“X軸”) plt.ylabel(“Y軸”) plt.grid(True, alpha=0.3)
📝 ステップ5: レイアウト調整と表示

plt.tight_layout()でグラフ同士の重なりを自動調整し、plt.show()で表示します。

# レイアウトを自動調整(タイトルや軸ラベルが重ならないように) plt.tight_layout() # グラフを表示 plt.show()

完成コード(1行2列のsubplot)

上記のステップをまとめた完成コードです。以下をそのままコピーして実行できます。

※コードが長い場合は横スクロールできます

import matplotlib.pyplot as plt # グラフに使うデータを用意 x = [1, 2, 3, 4, 5] y1 = [2, 4, 6, 8, 10] y2 = [1, 3, 5, 7, 9] # Figure(キャンバス)を作成 plt.figure(figsize=(12, 5)) # 左側のグラフ(1行2列の1番目) plt.subplot(1, 2, 1) plt.plot(x, y1, marker=’o’, color=’steelblue’) plt.title(“グラフ1: 直線的な増加”, fontsize=14, fontweight=’bold’) plt.xlabel(“X軸”) plt.ylabel(“Y軸”) plt.grid(True, alpha=0.3) # 右側のグラフ(1行2列の2番目) plt.subplot(1, 2, 2) plt.plot(x, y2, marker=’s’, color=’coral’) plt.title(“グラフ2: 奇数の増加”, fontsize=14, fontweight=’bold’) plt.xlabel(“X軸”) plt.ylabel(“Y軸”) plt.grid(True, alpha=0.3) # レイアウトを自動調整して表示 plt.tight_layout() plt.show()
【実行結果のイメージ】 ┌─────────────────────────────────────────────────────┐ │ │ │ グラフ1: 直線的な増加 グラフ2: 奇数の増加 │ │ │ │ 10 ┤ ● 9 ┤ ■ │ │ 8 ┤ ● 7 ┤ ■ │ │ 6 ┤ ● 5 ┤ ■ │ │ 4 ┤ ● 3 ┤ ■ │ │ 2 ┤ ● 1 ┤ ■ │ │ └───────── └───────── │ │ 1 2 3 4 5 1 2 3 4 5 │ │ │ └─────────────────────────────────────────────────────┘

📐 3. plt.subplots()の使い方(推奨される方法)

subplot()とsubplots()の違い

先ほどのplt.subplot()は、グラフを1つずつ作成する方法でした。

これに対してplt.subplots()(末尾に「s」が付く)は、最初にすべてのグラフ領域を一度に作成する方法です。こちらの方が推奨される書き方です。

💡 subplot() と subplots() の違い
項目 plt.subplot() plt.subplots()(推奨)
作成タイミング グラフを1つずつ作成 最初に全部まとめて作成
基本的な書き方 plt.subplot(1, 2, 1) fig, axes = plt.subplots(1, 2)
グラフへのアクセス plt.plot() で直接描画 axes[0].plot() で指定
メリット 直感的でわかりやすい コードが整理しやすい

plt.subplots()の基本的な書き方

plt.subplots()を使うと、FigureとAxes(グラフ領域)を同時に取得できます。

【plt.subplots() の書き方】 fig, axes = plt.subplots(行数, 列数, figsize=(幅, 高さ)) ・fig: Figure(キャンバス)を受け取る変数 ・axes: Axes(グラフ領域)の配列を受け取る変数 ・figsize: 図全体のサイズ(横, 縦)をインチで指定 【例】1行2列の場合 fig, axes = plt.subplots(1, 2, figsize=(12, 5)) → axes[0] = 左側のグラフ → axes[1] = 右側のグラフ 【例】2行2列の場合 fig, axes = plt.subplots(2, 2, figsize=(12, 10)) → axes[0, 0] = 左上のグラフ → axes[0, 1] = 右上のグラフ → axes[1, 0] = 左下のグラフ → axes[1, 1] = 右下のグラフ

1行2列のグラフを作成する(subplots版)

先ほどと同じ「左右に2つのグラフを並べる」例を、plt.subplots()で書き直してみましょう。

📝 ステップ1: ライブラリとデータの準備

この部分は先ほどと同じです。

import matplotlib.pyplot as plt # グラフに使うデータを用意 x = [1, 2, 3, 4, 5] y1 = [2, 4, 6, 8, 10] y2 = [1, 3, 5, 7, 9]
📝 ステップ2: FigureとAxesを同時に作成

plt.subplots()でFigure(キャンバス)とAxes(グラフ領域)を一度に作成します。

# 1行2列のsubplotsを作成 # fig = キャンバス全体 # axes = グラフ領域の配列(axes[0]が左、axes[1]が右) fig, axes = plt.subplots(1, 2, figsize=(12, 5))
📝 ステップ3: axes[0]に左側のグラフを描く

axes[0]を使って左側のグラフ領域に描画します。plt.plot()ではなく、axes[0].plot()と書く点に注意してください。

# 左側のグラフ(axes[0]) axes[0].plot(x, y1, marker=’o’, color=’steelblue’) axes[0].set_title(“グラフ1: 直線的な増加”, fontsize=14, fontweight=’bold’) axes[0].set_xlabel(“X軸”) # plt.xlabel() ではなく set_xlabel() axes[0].set_ylabel(“Y軸”) # plt.ylabel() ではなく set_ylabel() axes[0].grid(True, alpha=0.3)
⚠️ 関数名の違いに注意!

subplots()を使う場合、関数名が少し変わります。

plt.〇〇() の場合 axes[n].〇〇() の場合
plt.title() axes[n].set_title()
plt.xlabel() axes[n].set_xlabel()
plt.ylabel() axes[n].set_ylabel()
plt.xlim() axes[n].set_xlim()

覚え方:axes を使う場合は「set_」を付ける!

📝 ステップ4: axes[1]に右側のグラフを描く

axes[1]を使って右側のグラフ領域に描画します。

# 右側のグラフ(axes[1]) axes[1].plot(x, y2, marker=’s’, color=’coral’) axes[1].set_title(“グラフ2: 奇数の増加”, fontsize=14, fontweight=’bold’) axes[1].set_xlabel(“X軸”) axes[1].set_ylabel(“Y軸”) axes[1].grid(True, alpha=0.3)
📝 ステップ5: レイアウト調整と表示

この部分は先ほどと同じです。

# レイアウトを自動調整して表示 plt.tight_layout() plt.show()

完成コード(subplots版・1行2列)

上記のステップをまとめた完成コードです。

※コードが長い場合は横スクロールできます

import matplotlib.pyplot as plt # グラフに使うデータを用意 x = [1, 2, 3, 4, 5] y1 = [2, 4, 6, 8, 10] y2 = [1, 3, 5, 7, 9] # 1行2列のsubplotsを作成 fig, axes = plt.subplots(1, 2, figsize=(12, 5)) # 左側のグラフ(axes[0]) axes[0].plot(x, y1, marker=’o’, color=’steelblue’) axes[0].set_title(“グラフ1: 直線的な増加”, fontsize=14, fontweight=’bold’) axes[0].set_xlabel(“X軸”) axes[0].set_ylabel(“Y軸”) axes[0].grid(True, alpha=0.3) # 右側のグラフ(axes[1]) axes[1].plot(x, y2, marker=’s’, color=’coral’) axes[1].set_title(“グラフ2: 奇数の増加”, fontsize=14, fontweight=’bold’) axes[1].set_xlabel(“X軸”) axes[1].set_ylabel(“Y軸”) axes[1].grid(True, alpha=0.3) # レイアウトを自動調整して表示 plt.tight_layout() plt.show()

📊 4. 2×2のグリッドレイアウト

2行2列のグラフを作成する

次に、2行2列(合計4つ)のグラフを配置する方法を学びましょう。この配置は、ダッシュボードやレポートでよく使われます。

2行2列でのaxesのアクセス方法

2行2列の場合、axesは2次元配列になります。axes[行, 列]の形式でアクセスします。

【2行2列のaxesの配置】 fig, axes = plt.subplots(2, 2, figsize=(12, 10)) ┌─────────────┬─────────────┐ │ │ │ │ axes[0, 0] │ axes[0, 1] │ ← 0行目 │ (左上) │ (右上) │ │ │ │ ├─────────────┼─────────────┤ │ │ │ │ axes[1, 0] │ axes[1, 1] │ ← 1行目 │ (左下) │ (右下) │ │ │ │ └─────────────┴─────────────┘ ↑ ↑ 0列目 1列目 【覚え方】 ・axes[行番号, 列番号] ・行も列も 0 から始まる ・左上が [0, 0]、右下が [1, 1]

完成コード(2×2グリッド)

4つの異なる数学関数(sin, cos, exp, log)をグラフにする例です。

※コードが長い場合は横スクロールできます

import matplotlib.pyplot as plt import numpy as np # データを準備(0から10までを100等分した数列) x = np.linspace(0, 10, 100) # 2行2列のsubplotsを作成 fig, axes = plt.subplots(2, 2, figsize=(12, 10)) # 左上(axes[0, 0]): sin関数 axes[0, 0].plot(x, np.sin(x), color=’steelblue’, linewidth=2) axes[0, 0].set_title(“sin(x)”, fontsize=14, fontweight=’bold’) axes[0, 0].set_xlabel(“x”) axes[0, 0].set_ylabel(“y”) axes[0, 0].grid(True, alpha=0.3) # 右上(axes[0, 1]): cos関数 axes[0, 1].plot(x, np.cos(x), color=’coral’, linewidth=2) axes[0, 1].set_title(“cos(x)”, fontsize=14, fontweight=’bold’) axes[0, 1].set_xlabel(“x”) axes[0, 1].set_ylabel(“y”) axes[0, 1].grid(True, alpha=0.3) # 左下(axes[1, 0]): exp関数(指数関数) axes[1, 0].plot(x, np.exp(x/5), color=’forestgreen’, linewidth=2) axes[1, 0].set_title(“exp(x/5)”, fontsize=14, fontweight=’bold’) axes[1, 0].set_xlabel(“x”) axes[1, 0].set_ylabel(“y”) axes[1, 0].grid(True, alpha=0.3) # 右下(axes[1, 1]): log関数(対数関数) axes[1, 1].plot(x, np.log(x+1), color=’darkorange’, linewidth=2) axes[1, 1].set_title(“log(x+1)”, fontsize=14, fontweight=’bold’) axes[1, 1].set_xlabel(“x”) axes[1, 1].set_ylabel(“y”) axes[1, 1].grid(True, alpha=0.3) # レイアウトを自動調整して表示 plt.tight_layout() plt.show()
💡 np.linspace()とは

np.linspace(開始, 終了, 個数)は、指定した範囲を均等に分割した数列を作る関数です。

例:np.linspace(0, 10, 100) は、0から10までを100個に分割した数列を作ります。滑らかな曲線を描くために使います。

📏 5. 図のサイズと余白の調整

figsize(図全体のサイズ)

figsizeは、Figure全体の大きさを指定するパラメータです。figsize=(幅, 高さ)の形式で、単位はインチです。

📐 推奨されるfigsizeの値
レイアウト 推奨サイズ 補足
1行2列 (12, 5) または (14, 6) 横長のレイアウト
2行2列 (12, 10) または (14, 12) 正方形に近いレイアウト
1行3列 (15, 5) または (18, 6) かなり横長のレイアウト
3行1列 (8, 12) または (10, 15) 縦長のレイアウト

tight_layout()(自動余白調整)

plt.tight_layout()は、グラフ同士の間隔を自動的に調整する関数です。タイトルや軸ラベルが重ならないように、適切な余白を設定してくれます。

必ずplt.show()の前に呼び出してください。これを忘れると、グラフが重なって見にくくなることがあります。

# tight_layout()の使い方 fig, axes = plt.subplots(2, 2, figsize=(12, 10)) # (グラフを描画するコード) # tight_layout()を必ず呼ぶ! plt.tight_layout() # 表示 plt.show()

suptitle()で全体タイトルを追加

plt.suptitle()は、Figure全体に1つのタイトルを追加する関数です。個々のグラフのタイトルとは別に、全体を説明するタイトルを付けたいときに使います。

# 全体タイトルを追加 plt.suptitle(“月次ダッシュボード”, fontsize=18, fontweight=’bold’) # suptitleを使う場合、tight_layout()の代わりに # 上部に余白を確保する plt.tight_layout() plt.subplots_adjust(top=0.93) # 上部に7%の余白を追加
💡 suptitleを使うときの注意

suptitle()で全体タイトルを追加すると、tight_layout()だけではタイトルがグラフに重なることがあります。

解決策:plt.subplots_adjust(top=0.93) を追加して、上部に余白を確保します。topの値は0.9〜0.95くらいが適切です(1.0だと上端ぴったり)。

📊 6. 実践的な例:ダッシュボード風レイアウト

ビジネスダッシュボードの作成

実際のビジネスシーンを想定した、月次ダッシュボードを作成してみましょう。売上推移、利益推移、来店客数、売上と利益の関係を1つの図にまとめます。

コードの解説

長いコードですので、セクションごとに解説します。

📝 データの準備

6ヶ月分の架空のビジネスデータを用意します。

import matplotlib.pyplot as plt # 6ヶ月分のデータ months = [‘1月’, ‘2月’, ‘3月’, ‘4月’, ‘5月’, ‘6月’] sales = [100, 120, 150, 130, 160, 180] # 売上(万円) profit = [20, 25, 35, 28, 38, 45] # 利益(万円) visitors = [850, 920, 1050, 980, 1120, 1250] # 来店客数(人)
📝 FigureとAxesの作成

2行2列のsubplotsを作成し、全体タイトルを設定します。

# 2行2列のsubplotsを作成 fig, axes = plt.subplots(2, 2, figsize=(14, 10)) # 全体タイトル plt.suptitle(“月次ダッシュボード”, fontsize=18, fontweight=’bold’)
📝 左上:売上推移(折れ線グラフ)

月ごとの売上を折れ線グラフで表示します。

# 左上: 売上推移 axes[0, 0].plot(months, sales, marker=’o’, linewidth=2.5, color=’steelblue’) axes[0, 0].set_title(“月別売上推移”, fontsize=14, fontweight=’bold’) axes[0, 0].set_ylabel(“売上(万円)”, fontsize=11) axes[0, 0].grid(True, alpha=0.3)
📝 右上:利益推移(折れ線グラフ)

月ごとの利益を折れ線グラフで表示します。売上とは別の色を使います。

# 右上: 利益推移 axes[0, 1].plot(months, profit, marker=’s’, linewidth=2.5, color=’coral’) axes[0, 1].set_title(“月別利益推移”, fontsize=14, fontweight=’bold’) axes[0, 1].set_ylabel(“利益(万円)”, fontsize=11) axes[0, 1].grid(True, alpha=0.3)
📝 左下:来店客数(棒グラフ)

月ごとの来店客数を棒グラフで表示します。棒グラフは.bar()を使います。

# 左下: 来店客数(棒グラフ) axes[1, 0].bar(months, visitors, color=’forestgreen’, edgecolor=’black’) axes[1, 0].set_title(“月別来店客数”, fontsize=14, fontweight=’bold’) axes[1, 0].set_ylabel(“人数”, fontsize=11) axes[1, 0].grid(True, axis=’y’, alpha=0.3) # Y軸方向のみグリッド表示
📝 右下:売上と利益の関係(散布図)

売上と利益の相関関係を散布図で表示します。散布図は.scatter()を使います。

# 右下: 売上と利益の散布図 axes[1, 1].scatter(sales, profit, s=150, alpha=0.6, color=’darkorange’, edgecolors=’black’, linewidth=1.5) axes[1, 1].set_title(“売上と利益の関係”, fontsize=14, fontweight=’bold’) axes[1, 1].set_xlabel(“売上(万円)”, fontsize=11) axes[1, 1].set_ylabel(“利益(万円)”, fontsize=11) axes[1, 1].grid(True, alpha=0.3)
📝 レイアウト調整と表示

全体タイトルがあるので、上部に余白を確保します。

# レイアウト調整 plt.tight_layout() plt.subplots_adjust(top=0.93) # 全体タイトル用の余白 # 表示 plt.show()

完成コード(ダッシュボード)

上記をまとめた完成コードです。

※コードが長い場合は横スクロールできます

import matplotlib.pyplot as plt # 6ヶ月分のデータ months = [‘1月’, ‘2月’, ‘3月’, ‘4月’, ‘5月’, ‘6月’] sales = [100, 120, 150, 130, 160, 180] profit = [20, 25, 35, 28, 38, 45] visitors = [850, 920, 1050, 980, 1120, 1250] # 2行2列のsubplotsを作成 fig, axes = plt.subplots(2, 2, figsize=(14, 10)) # 全体タイトル plt.suptitle(“月次ダッシュボード”, fontsize=18, fontweight=’bold’) # 左上: 売上推移 axes[0, 0].plot(months, sales, marker=’o’, linewidth=2.5, color=’steelblue’) axes[0, 0].set_title(“月別売上推移”, fontsize=14, fontweight=’bold’) axes[0, 0].set_ylabel(“売上(万円)”, fontsize=11) axes[0, 0].grid(True, alpha=0.3) # 右上: 利益推移 axes[0, 1].plot(months, profit, marker=’s’, linewidth=2.5, color=’coral’) axes[0, 1].set_title(“月別利益推移”, fontsize=14, fontweight=’bold’) axes[0, 1].set_ylabel(“利益(万円)”, fontsize=11) axes[0, 1].grid(True, alpha=0.3) # 左下: 来店客数 axes[1, 0].bar(months, visitors, color=’forestgreen’, edgecolor=’black’) axes[1, 0].set_title(“月別来店客数”, fontsize=14, fontweight=’bold’) axes[1, 0].set_ylabel(“人数”, fontsize=11) axes[1, 0].grid(True, axis=’y’, alpha=0.3) # 右下: 売上と利益の散布図 axes[1, 1].scatter(sales, profit, s=150, alpha=0.6, color=’darkorange’, edgecolors=’black’, linewidth=1.5) axes[1, 1].set_title(“売上と利益の関係”, fontsize=14, fontweight=’bold’) axes[1, 1].set_xlabel(“売上(万円)”, fontsize=11) axes[1, 1].set_ylabel(“利益(万円)”, fontsize=11) axes[1, 1].grid(True, alpha=0.3) # レイアウト調整と表示 plt.tight_layout() plt.subplots_adjust(top=0.93) plt.show()
【実行結果のイメージ】 月次ダッシュボード ┌─────────────────┬─────────────────┐ │ │ │ │ 月別売上推移 │ 月別利益推移 │ │ 180●─ │ 45■─ │ │ ╲ │ ╲ │ │ 100●──● │ 20■──■ │ │ 1月 6月 │ 1月 6月 │ │ │ │ ├─────────────────┼─────────────────┤ │ │ │ │ 月別来店客数 │ 売上と利益の関係 │ │ ████ ████ │ ● │ │ ██ ██ ██ │ ● ● │ │ 1月 6月 │ ● ● │ │ │ 100 180 │ │ │ │ └─────────────────┴─────────────────┘

📈 7. 同じデータを異なるグラフで表現

データの見せ方を比較する

同じデータでも、グラフの種類によって見え方が大きく変わります。ヒストグラム、箱ひげ図、バイオリン図を並べて比較してみましょう。

※コードが長い場合は横スクロールできます

import matplotlib.pyplot as plt import numpy as np # ランダムなテストデータを生成 np.random.seed(42) # 再現性のためにシードを固定 data = np.random.normal(70, 15, 200) # 平均70、標準偏差15の正規分布データ200個 # 1行3列のsubplotsを作成 fig, axes = plt.subplots(1, 3, figsize=(15, 5)) # 全体タイトル plt.suptitle(“同じデータを異なるグラフで表現”, fontsize=16, fontweight=’bold’) # 左: ヒストグラム(データの分布を見る) axes[0].hist(data, bins=20, color=’steelblue’, edgecolor=’black’, alpha=0.7) axes[0].set_title(“ヒストグラム”, fontsize=14, fontweight=’bold’) axes[0].set_xlabel(“値”, fontsize=11) axes[0].set_ylabel(“頻度”, fontsize=11) axes[0].grid(True, axis=’y’, alpha=0.3) # 中央: 箱ひげ図(中央値や外れ値を見る) box = axes[1].boxplot(data, vert=True, patch_artist=True) box[‘boxes’][0].set_facecolor(‘coral’) box[‘boxes’][0].set_alpha(0.7) axes[1].set_title(“箱ひげ図”, fontsize=14, fontweight=’bold’) axes[1].set_ylabel(“値”, fontsize=11) axes[1].grid(True, axis=’y’, alpha=0.3) # 右: バイオリン図(分布の形状を見る) parts = axes[2].violinplot([data], positions=[1], showmeans=True) for pc in parts[‘bodies’]: pc.set_facecolor(‘forestgreen’) pc.set_alpha(0.7) axes[2].set_title(“バイオリン図”, fontsize=14, fontweight=’bold’) axes[2].set_ylabel(“値”, fontsize=11) axes[2].set_xticks([1]) axes[2].set_xticklabels([‘データ’]) axes[2].grid(True, axis=’y’, alpha=0.3) # レイアウト調整と表示 plt.tight_layout() plt.subplots_adjust(top=0.88) plt.show()
📊 各グラフの特徴
グラフ種類 特徴 わかること
ヒストグラム データを区間に分けて棒で表示 データの分布、どの範囲に多いか
箱ひげ図 四分位数を箱と線で表示 中央値、ばらつき、外れ値
バイオリン図 分布の形状を曲線で表示 分布の形(山が1つか2つかなど)

📝 STEP 9 のまとめ

✅ このステップで学んだこと
トピック 重要ポイント
Figure と Axes Figureはキャンバス、Axesは個々のグラフ
plt.subplot() グラフを1つずつ作成。subplot(行, 列, 位置)
plt.subplots() 一度に全部作成(推奨)。fig, axes = subplots(行, 列)
axesでのアクセス 1行:axes[n]、複数行:axes[行, 列]
関数名の違い axes使用時は set_title(), set_xlabel() など「set_」を付ける
tight_layout() 余白を自動調整。show()の前に必ず呼ぶ
suptitle() 全体タイトル。subplots_adjust(top=0.93)と併用
💡 最重要ポイント

複数のグラフを並べることで、複数の視点からデータを分析・比較できます。

plt.subplots()を使えば、コードがすっきりして管理しやすくなります。

tight_layout()を忘れずに!これを忘れると、タイトルや軸ラベルが重なってしまいます。次のステップでは、軸の詳細設定や注釈(アノテーション)の追加方法を学びます!

📝 実践演習

演習 1 基礎

plt.subplots()を使って、1行2列のグラフを作成してください。
左側に折れ線グラフ、右側に棒グラフを表示してください。
データは自由に設定してOKです。

【解答例】
import matplotlib.pyplot as plt # データの準備 x = [1, 2, 3, 4, 5] y = [2, 4, 6, 8, 10] # 1行2列のsubplotsを作成 fig, axes = plt.subplots(1, 2, figsize=(12, 5)) # 左側: 折れ線グラフ axes[0].plot(x, y, marker=’o’, linewidth=2, color=’steelblue’) axes[0].set_title(“折れ線グラフ”, fontsize=14, fontweight=’bold’) axes[0].set_xlabel(“X軸”) axes[0].set_ylabel(“Y軸”) axes[0].grid(True, alpha=0.3) # 右側: 棒グラフ axes[1].bar(x, y, color=’coral’, edgecolor=’black’) axes[1].set_title(“棒グラフ”, fontsize=14, fontweight=’bold’) axes[1].set_xlabel(“X軸”) axes[1].set_ylabel(“Y軸”) axes[1].grid(True, axis=’y’, alpha=0.3) # レイアウト調整と表示 plt.tight_layout() plt.show()

ポイント:axes[0]が左側、axes[1]が右側です。axesを使う場合は set_title(), set_xlabel() のように「set_」を付けることを忘れずに!

演習 2 応用

2行2列のsubplotsを作成し、4つの異なるグラフを表示してください。
(折れ線、棒、散布図、ヒストグラム)
全体タイトルを「データ分析レポート」としてください。

【解答例】
import matplotlib.pyplot as plt import numpy as np # データの準備 x = [1, 2, 3, 4, 5] y = [2, 4, 6, 8, 10] np.random.seed(42) data = np.random.normal(50, 10, 100) # 2行2列のsubplotsを作成 fig, axes = plt.subplots(2, 2, figsize=(12, 10)) # 全体タイトル plt.suptitle(“データ分析レポート”, fontsize=18, fontweight=’bold’) # 左上: 折れ線グラフ axes[0, 0].plot(x, y, marker=’o’, linewidth=2, color=’steelblue’) axes[0, 0].set_title(“折れ線グラフ”, fontsize=14, fontweight=’bold’) axes[0, 0].grid(True, alpha=0.3) # 右上: 棒グラフ axes[0, 1].bar(x, y, color=’coral’, edgecolor=’black’) axes[0, 1].set_title(“棒グラフ”, fontsize=14, fontweight=’bold’) axes[0, 1].grid(True, axis=’y’, alpha=0.3) # 左下: 散布図 axes[1, 0].scatter(x, y, s=150, alpha=0.6, color=’forestgreen’, edgecolors=’black’) axes[1, 0].set_title(“散布図”, fontsize=14, fontweight=’bold’) axes[1, 0].grid(True, alpha=0.3) # 右下: ヒストグラム axes[1, 1].hist(data, bins=15, color=’darkorange’, edgecolor=’black’, alpha=0.7) axes[1, 1].set_title(“ヒストグラム”, fontsize=14, fontweight=’bold’) axes[1, 1].grid(True, axis=’y’, alpha=0.3) # レイアウト調整と表示 plt.tight_layout() plt.subplots_adjust(top=0.93) plt.show()

ポイント:2次元のaxesは axes[行, 列] でアクセスします。suptitle()を使う場合は subplots_adjust(top=0.93) で上部に余白を確保しましょう。

演習 3 発展

自分のビジネスや興味のある分野のデータを想定して、
4つのグラフで構成されるダッシュボードを作成してください。
全体タイトル、各グラフのタイトル、軸ラベルを適切に設定してください。

【解答のポイント】

以下の点を意識してダッシュボードを作成してください:

  1. データの関連性:4つのグラフは同じテーマに関連したデータにする
  2. グラフの種類:データの性質に合ったグラフを選ぶ(時系列→折れ線、比較→棒、相関→散布図、分布→ヒストグラム)
  3. 全体タイトル:ダッシュボード全体の目的がわかるタイトルを付ける
  4. 各グラフのタイトル:「何がわかるか」を伝えるタイトルにする
  5. 軸ラベル:単位を含めて明確に記載する
  6. 色の統一感:全体で使う色のトーンを揃える

例:

  • ECサイト運営:売上推移、商品別売上、顧客数推移、売上と広告費の関係
  • 健康管理:体重推移、運動時間、摂取カロリー分布、運動と体重変化の関係
  • 学習進捗:学習時間推移、科目別時間配分、テスト点数推移、学習時間と成績の関係

❓ よくある質問

Q1: subplot()とsubplots()はどちらを使うべきですか?
plt.subplots()(複数形)を推奨します。一度にすべてのsubplotを作成でき、コードも整理しやすいです。axesオブジェクトを使ってグラフを操作するため、どのグラフに対する操作かが明確になります。ほとんどの場合、subplots()を使う方が良いでしょう。
Q2: tight_layout()を使ってもタイトルがグラフに重なります。どうすればいいですか?
subplots_adjust()で余白を調整しましょう。特にsuptitle()で全体タイトルを追加した場合、タイトルが重なりやすいです。plt.subplots_adjust(top=0.93) のように、top引数で上部の余白を確保します。値は0.9〜0.95くらいが適切で、タイトルが長い場合は0.88くらいまで下げることもあります。
Q3: 3つのグラフを横に並べたいのですが、どうすればいいですか?
1行3列にしましょう。fig, axes = plt.subplots(1, 3, figsize=(15, 5)) として、axes[0]、axes[1]、axes[2] にそれぞれグラフを描きます。figsizeは横長(15〜18インチ)にすると、各グラフが見やすくなります。
Q4: axes[0, 0]とaxes[0][0]の違いは何ですか?
どちらも同じ意味です。Pythonでは、2次元配列へのアクセスを axes[0, 0](カンマ区切り)または axes[0][0](角括弧2つ)のどちらでも書けます。一般的には axes[0, 0] の方が簡潔で、NumPy配列でよく使われる書き方です。
Q5: set_title()とplt.title()はなぜ別々に存在するのですか?
「どのグラフに対する操作か」を明確にするためです。plt.title()は「現在アクティブなAxes」に対して操作を行いますが、axes[0].set_title()は「axes[0]という特定のAxes」に対して操作を行います。subplots()で複数のグラフを扱う場合、どのグラフに対する操作かを明示するために、set_title()のようなメソッドを使います。

📝

学習メモ

データ可視化マスター - Step 9

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE