matplotlib は Python の可視化ライブラリの中で最も広く使われている定番です。pandas / NumPy のオブジェクトをそのまま描画できるため、分析の途中経過を素早くグラフにする手段として重要です。
本記事では、matplotlib の基本構造(Figure と Axes)を押さえた上で、折れ線・棒・ヒストグラムの 3 種類を株価データを題材に描きます。
目次
- インストール
- Figure と Axes の関係
- 折れ線:株価の推移
- 複数系列を重ねる
- 棒グラフ:出来高
- ヒストグラム:リターンの分布
- サブプロット:価格と出来高を同居させる
- 体裁のチェックリスト
インストール
pip install matplotlib pandas検証バージョン: Python 3.12.5 / matplotlib 3.9.2 / pandas 2.2.3
Figure と Axes の関係
matplotlib のグラフは 2 階層で構成されます。
- Figure: 紙の 1 枚に相当。サイズ・解像度・全体タイトルを持つ
- Axes: 紙の上に置く描画領域(座標系を 1 つ持つ)。1 つの Figure に複数置ける
plt.subplots() で Figure と Axes を同時に作るのが現代的な書き方です。
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 4))ax.plot([1, 2, 3], [1, 4, 9])ax.set_title("y = x^2")plt.tight_layout()plt.savefig("fig1.png", dpi=120)plt.close(fig)plt.tight_layout() でラベル類のはみ出しを防ぎ、plt.savefig で画像保存します。plt.show() は対話環境(Jupyter / IPython)で使い、ファイル化するなら savefig で十分です。
折れ線:株価の推移
最もよく使うのが折れ線(line plot)です。日付を x 軸、終値を y 軸に取ります。
import numpy as npimport pandas as pdimport matplotlib.pyplot as plt
rng = np.random.default_rng(0)dates = pd.date_range("2026-01-05", periods=100, freq="B")close = pd.Series(2900 + rng.normal(0, 30, 100).cumsum(), index=dates, name="C")
fig, ax = plt.subplots(figsize=(10, 4))ax.plot(close.index, close.values, color="C0", linewidth=1.4, label="7203 close")ax.set_title("7203 close (synthetic)")ax.set_xlabel("Date")ax.set_ylabel("C (JPY)")ax.grid(alpha=0.3)ax.legend()plt.tight_layout()plt.savefig("close_line.png", dpi=120)plt.close(fig)
体裁のポイントは次の通りです。
color="C0"は標準色サイクルの 1 番目(濃い青)。別系列は"C1""C2"と進めるlinewidthは 1.4 程度が見やすいgrid(alpha=0.3)でうっすらしたグリッドを入れると、値の読み取りが楽になるlegend()を呼び出さないと凡例は表示されない
複数系列を重ねる
複数銘柄を同じ軸に重ねる場合は ax.plot を繰り返すだけです。
close_b = pd.Series(2900 + rng.normal(0, 25, 100).cumsum(), index=dates)close_c = pd.Series(2900 + rng.normal(0, 35, 100).cumsum(), index=dates)
fig, ax = plt.subplots(figsize=(10, 4))ax.plot(dates, close.values, label="A", color="C0")ax.plot(dates, close_b.values, label="B", color="C1")ax.plot(dates, close_c.values, label="C", color="C2")ax.set_title("Three synthetic series")ax.set_ylabel("C (JPY)")ax.grid(alpha=0.3)ax.legend(loc="upper left")plt.tight_layout()plt.savefig("multi_line.png", dpi=120)plt.close(fig)スケールが大きく違う 2 つの系列を重ねたい場合は、第 2 軸を作ります。
fig, ax1 = plt.subplots(figsize=(10, 4))ax1.plot(dates, close.values, color="C0", label="close")ax1.set_ylabel("C (JPY)")
ax2 = ax1.twinx()volume = pd.Series(rng.integers(8_000_000, 15_000_000, 100), index=dates)ax2.bar(dates, volume.values, alpha=0.2, color="gray", label="volume")ax2.set_ylabel("Vo")
plt.tight_layout()plt.savefig("dual_axis.png", dpi=120)plt.close(fig)第 2 軸の使いすぎは可読性を下げます。「価格と出来高」「価格と指標値」のように単位が明確に異なるときに限定するのが定石です。
棒グラフ:出来高
出来高は棒グラフ(bar plot)が定番です。
fig, ax = plt.subplots(figsize=(10, 3.5))ax.bar(dates, volume.values, color="C0", width=0.8)ax.set_title("Daily volume")ax.set_ylabel("Vo")ax.grid(axis="y", alpha=0.3)plt.tight_layout()plt.savefig("volume_bar.png", dpi=120)plt.close(fig)
grid(axis="y") で y 方向だけにグリッドを入れます。棒グラフは x 方向のグリッドが邪魔になりがちです。
ヒストグラム:リターンの分布
リターン(変化率)を見るときはヒストグラム(histogram)です。
returns = close.pct_change().dropna()
fig, ax = plt.subplots(figsize=(7, 4))ax.hist(returns, bins=30, color="C0", edgecolor="white")ax.set_title("Daily return distribution")ax.set_xlabel("Return")ax.set_ylabel("Frequency")ax.axvline(0, color="black", linewidth=0.8)ax.grid(alpha=0.3)plt.tight_layout()plt.savefig("return_hist.png", dpi=120)plt.close(fig)
bins の数で見え方が変わります。少なすぎると粗く、多すぎるとガタつきます。データ件数が 100 程度なら 20 〜 30 が目安です。
axvline(0, ...) でゼロ位置に縦線を引くと、上昇日と下落日の偏りが分かりやすくなります。
サブプロット:価格と出来高を同居させる
plt.subplots に行・列を指定すると複数の Axes を作れます。価格と出来高を上下に並べる例です。
fig, (ax1, ax2) = plt.subplots( 2, 1, figsize=(10, 6), sharex=True, gridspec_kw={"height_ratios": [3, 1]},)ax1.plot(dates, close.values, color="C0")ax1.set_ylabel("C")ax1.grid(alpha=0.3)
ax2.bar(dates, volume.values, color="gray")ax2.set_ylabel("Vo")ax2.grid(axis="y", alpha=0.3)
fig.suptitle("Price and volume")plt.tight_layout()plt.savefig("price_volume.png", dpi=120)plt.close(fig)sharex=True で x 軸を共有し、height_ratios で上 3 : 下 1 の比率にしています。ローソク足チャートに近い見た目を作る基本パターンです。
体裁のチェックリスト
人に見せるチャートを作るときに見るべき項目をまとめます。
- タイトル(
set_title)があるか - 軸ラベル(
set_xlabel/set_ylabel)があるか - 単位が分かるか(円・%・件数など)
- 凡例(
legend)が必要なのに省略していないか - 複数系列で色が衝突していないか(色覚のことも考慮)
- 数値の桁が見にくいときに
,区切りにしてあるか
, 区切りは FuncFormatter で簡単に入れられます。
from matplotlib.ticker import FuncFormatter
fig, ax = plt.subplots(figsize=(8, 3))ax.plot(dates, close.values * 100)ax.yaxis.set_major_formatter(FuncFormatter(lambda x, pos: f"{x:,.0f}"))plt.tight_layout()plt.savefig("formatted.png", dpi=120)plt.close(fig)生成AI へのプロンプト例
可視化は「描きたい絵」を具体的に書くと、出力ブレが減ります。
matplotlib で次のチャートを描くコードを書いてください。
入力:- df(列: Date, C, sma_25, sma_75, Vo)
要件:- 上下 2 段のサブプロット(高さ比 3:1)、x 軸を共有- 上段: C を線、sma_25 / sma_75 を細線で重ねる、凡例付き- 下段: Vo を棒グラフ、色は薄いグレー- 画像は dpi=120 で chart.png に保存- matplotlib 3.9 系、tight_layout を使用「サブプロット構成」「線の種類」「色」「保存先」を順に書くと、再現性のあるコードが返ってきます。
まとめ
- matplotlib は Figure(紙) と Axes(描画領域) の 2 層構造
- 折れ線・棒・ヒストグラムの 3 種類で大半の用途は足りる
- 複数系列・第 2 軸・サブプロットを組み合わせて情報量を上げられる
- 体裁(タイトル・軸ラベル・凡例・グリッド)を欠かさないと、後で見返したときに意味が分かる