📋 このステップで学ぶこと
- 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を理解するには、まずFigureとAxesの関係を知ることが大切です。
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つのグラフで構成されるダッシュボードを作成してください。
全体タイトル、各グラフのタイトル、軸ラベルを適切に設定してください。
【解答のポイント】
以下の点を意識してダッシュボードを作成してください:
- データの関連性:4つのグラフは同じテーマに関連したデータにする
- グラフの種類:データの性質に合ったグラフを選ぶ(時系列→折れ線、比較→棒、相関→散布図、分布→ヒストグラム)
- 全体タイトル:ダッシュボード全体の目的がわかるタイトルを付ける
- 各グラフのタイトル:「何がわかるか」を伝えるタイトルにする
- 軸ラベル:単位を含めて明確に記載する
- 色の統一感:全体で使う色のトーンを揃える
例:
- 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()のようなメソッドを使います。
artnasekai
#artnasekai #学習メモ