PR

Seabornの応用:heatmapを使いこなす – 相関係数・annot・カラーバーまで見やすく描く方法

Python

Pythonのデータ可視化ライブラリSeabornは、データ分析の効率とわかりやすさを格段に高めてくれます。その中でもheatmap(ヒートマップ)は、表の形をしたデータを色の濃さで表し、大きい値・小さい値のまとまりや、項目どうしの相関を一目で見せてくれる便利な機能です。本記事では、heatmapの基本的な使い方から、相関係数を見やすく描くための応用まで、実例を交えながら解説していきます。

カテゴリデータ・分布データの可視化についてはこちら

この記事で分かること

  • heatmapに渡すデータの形(横長の表)と、基本の描き方
  • annotとfmtで、マスの中に数値を表示する方法
  • 相関係数のヒートマップを見やすくするcmap・vmin/vmax・center・maskの使い方
  • カラーバーの調整と、日本語ラベルの表示方法
  • heatmapでよく出るエラーと直し方

本記事のコードは、Python 3.12.1、seaborn 0.13.2、matplotlib 3.11.2、pandas 3.1.0、numpy 2.5.4 の環境で実行して確認しています。

スポンサーリンク

heatmapとは?

heatmapは、行と列からなる表(2次元のデータ)の値を、マスの色で表すグラフです。数字がずらりと並んだ表では気づきにくい「どこが大きいか」「どんな並び方をしているか」が、色の濃淡ですぐに分かるようになります。

  1. 表全体の傾向をつかむ: 月別・年別の売上や利用者数など、2つの軸で集計した表のパターン(季節性や増加傾向)を一目で見られます。
  2. 相関を確認する: 複数の列どうしの相関係数を並べた「相関行列」を色で表すと、関係の強い組み合わせがすぐに見つかります。機械学習の前処理でよく使われる使い方です。
  3. 数値と色を同時に見せる: マスの中に数値を書き込めるので、色で全体を見ながら、細かい値も確認できます。

matplotlibだけでヒートマップのように2次元のデータを色で描く方法(pcolormeshなど)は、こちらの記事で紹介しています。

matplotlibの応用: 2次元メッシュの描画方法

スポンサーリンク

データの準備

今回は、Seabornでサンプルとして準備されているデータを呼び出して使用します。load_datasetは初回にインターネットからデータをダウンロードするので、ネットにつながった環境で実行してください。Seabornそのものの基本はこちらの記事で解説しています。

Seabornの基礎:データの可視化をより美しく、効果的に

まずは、1949年から1960年までの月ごとの航空旅客数のデータ(flights)を使います。

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

flights = sns.load_dataset("flights")
flights_wide = flights.pivot(index="month", columns="year", values="passengers")
print(flights_wide.iloc[:3, :5])
year   1949  1950  1951  1952  1953
month
Jan     112   115   145   171   196
Feb     118   126   150   180   196
Mar     132   141   178   193   236

ここが一番のポイントです。flightsは元々「year・month・passengers」の3列が縦に長く並んだデータ(縦持ち)ですが、heatmapには行と列がそのまま縦軸・横軸になる横長の表(横持ち)を渡す必要があります。そこでpivotを使って、行を月、列を年、値を旅客数にした表に作り変えています。

よく使う引数

  • data: プロットする横長の表(データフレームや2次元配列)
  • annot / fmt: マスの中に数値を書くかどうかと、その書式
  • cmap: 色の組み合わせ(カラーマップ)
  • vmin / vmax / center: 色を割り当てる値の範囲と中心
  • mask: 表示しないマスの指定
  • cbar / cbar_kws: カラーバーの表示と調整
スポンサーリンク

基本の描き方:最小コード

横長の表をsns.heatmap()に渡すだけで描けます。行のラベル(月)が縦軸に、列のラベル(年)が横軸に自動で入ります。

plt.figure(figsize=(10, 8))
sns.heatmap(flights_wide)
plt.show()
Seabornのheatmapで描いた月別・年別の航空旅客数。年を追うごとに、また夏の月ほど色が明るくなっている

右側に年が進むほど色が明るく(値が大きく)なり、7月・8月の行が特に明るいことから、「旅客数は年々増えていて、夏に多い」という傾向が一目で分かります。

スポンサーリンク

annotとfmtで数値を表示する

annot

annot=Trueにすると、それぞれのマスの中に値が書き込まれます。

fmt

書き込む数値の書式を指定します。初期値は".2g"(有効数字2桁)なので、何も指定しないと「112」が「1.1e+02」のような表示になってしまいます。整数のデータならfmt="d"、小数を2桁で見せたいならfmt=".2f"を指定しましょう。あわせてlinewidthsでマスの間に線を入れると、数値が読みやすくなります。

plt.figure(figsize=(10, 8))
sns.heatmap(flights_wide, annot=True, fmt="d", linewidths=0.5)
plt.show()
annot=Trueとfmt="d"で、各マスに旅客数の整数値を書き込んだヒートマップ

文字の色は、マスの色に合わせて白か黒が自動で選ばれます。文字の大きさなどを変えたいときはannot_kws={"size": 8}のように指定できます。

スポンサーリンク

相関係数のヒートマップ:cmap・vmin/vmax・center

heatmapが一番よく使われるのが、相関係数の行列(相関行列)を描く場面です。ここではペンギンの体の大きさのデータ(penguins)を使います。pandasのcorr()で、数値の列どうしの相関係数を計算してから描きます。

penguins = sns.load_dataset("penguins")
corr = penguins.corr(numeric_only=True)

plt.figure(figsize=(10, 8))
sns.heatmap(corr, annot=True, fmt=".2f",
            cmap="coolwarm", vmin=-1, vmax=1, center=0)
plt.show()
penguinsの4つの数値列の相関行列を、coolwarmのカラーマップで-1から1の範囲に色分けしたヒートマップ

翼の長さ(flipper_length_mm)と体重(body_mass_g)の相関が0.87と強く、赤く表示されているのが分かります。逆に、くちばしの厚み(bill_depth_mm)は他の項目とマイナスの相関になっていて、青く表示されています。

cmap

色の組み合わせ(カラーマップ)を指定します。カラーマップには大きく分けて2つの種類があり、データに合わせて使い分けるのがコツです。

  1. 連続型(Sequential): 小さい値から大きい値へ、1方向に色が変わります。旅客数や売上のように「大きいほど多い」データ向けです。例: "rocket"(heatmapの初期値)、"viridis"、"Blues"、"YlGnBu"
  2. 発散型(Diverging): 真ん中の値を境に、プラス側とマイナス側で別の色になります。相関係数のように0を境に意味が分かれるデータ向けです。例: "coolwarm"、"RdBu_r"、"vlag"、"icefire"

カラーマップ名の最後に_rを付けると、色の順番が逆になります(例: "RdBu"はマイナスが赤、"RdBu_r"はプラスが赤)。

vmin / vmax / center

vminとvmaxは、色を割り当てる値の下限と上限です。指定しないと、データの最小値と最大値に合わせて自動で決まります。相関係数でこれを省略すると、例えば最小が-0.58なら-0.58が一番濃い青になり、弱い相関なのに強い相関のような色になってしまいます。相関係数を描くときは、取りうる範囲のvmin=-1, vmax=1を指定しておくのがおすすめです。

centerは、発散型カラーマップの「真ん中の色(白に近い色)」にする値です。相関係数ならcenter=0にすると、相関がないところが白っぽく、プラスとマイナスで色が分かれます。なお、cmapを指定せずにcenterだけを指定すると、Seabornは発散型の"icefire"を自動で使います。

スポンサーリンク

maskで上三角を隠す

相関行列は、対角線をはさんで左下と右上に同じ値が並びます(AとBの相関=BとAの相関)。また対角線は自分自身との相関なので、必ず1.00です。同じ情報が2回出てくると見づらいので、maskで右上半分を隠してみましょう。

maskには、データと同じ形の True / False の表を渡します。Trueのマスが表示されなくなります。numpyのnp.triuを使うと、対角線を含む右上半分だけがTrueの表を作れます。

mask = np.triu(np.ones_like(corr, dtype=bool))

plt.figure(figsize=(10, 8))
sns.heatmap(corr, mask=mask, annot=True, fmt=".2f",
            cmap="coolwarm", vmin=-1, vmax=1, center=0)
plt.show()
maskで対角線と右上半分を隠し、左下の三角形だけを表示した相関行列のヒートマップ

対角線の1.00も表示したい場合は、np.triu(..., k=1)のようにk=1を付けると、対角線より上だけを隠せます。

スポンサーリンク

カラーバーとマスの見た目を調整する

cbar_kws

右側のカラーバーの設定を辞書で渡します。"shrink"でカラーバーの長さを縮め、"label"でカラーバーに見出しを付けられます。カラーバー自体が不要ならcbar=Falseで消せます。

square / linewidths

square=Trueにするとマスが正方形になり、linewidthsでマスの間に線が入ります。線の色はlinecolorで変えられます(初期値は白)。

plt.figure(figsize=(10, 8))
sns.heatmap(corr, mask=mask, annot=True, fmt=".2f",
            cmap="coolwarm", vmin=-1, vmax=1, center=0,
            square=True, linewidths=0.5,
            cbar_kws={"shrink": 0.8, "label": "correlation"})
plt.show()
square=Trueで正方形のマスにし、カラーバーを短くしてcorrelationというラベルを付けた相関行列のヒートマップ
スポンサーリンク

日本語のラベルを表示する

matplotlibの初期フォントは日本語に対応していないため、そのまま日本語のラベルやタイトルを付けると、文字が「□」(豆腐)になってしまいます。plt.rcParams["font.family"]で日本語フォントを指定しておきましょう。Windowsなら標準で入っている「Meiryo」や「BIZ UDGothic」が使えます。

列名もrenameで日本語に置き換えてから描くと、そのまま軸のラベルが日本語になります。

plt.rcParams["font.family"] = "Meiryo"  # Windowsの場合。BIZ UDGothic でもOK

labels = {"bill_length_mm": "くちばしの長さ",
          "bill_depth_mm": "くちばしの厚み",
          "flipper_length_mm": "翼の長さ",
          "body_mass_g": "体重"}
corr_ja = corr.rename(index=labels, columns=labels)

plt.figure(figsize=(10, 8))
ax = sns.heatmap(corr_ja, mask=mask, annot=True, fmt=".2f",
                 cmap="coolwarm", vmin=-1, vmax=1, center=0,
                 square=True, linewidths=0.5,
                 cbar_kws={"shrink": 0.8, "label": "相関係数"})
ax.set_title("ペンギンの体の大きさの相関")
plt.show()
Meiryoフォントを指定して、軸ラベル・タイトル・カラーバーを日本語で表示した相関行列のヒートマップ

Macの場合は「Hiragino Sans」など、使っているパソコンに入っている日本語フォントの名前を指定してください。

スポンサーリンク

よくあるエラーと直し方

ValueError: could not convert string to float: ‘Adelie’

penguins.corr()のように、文字の列(種類名など)が入ったままのデータで相関係数を計算しようとすると出るエラーです。pandas 2.0から、corr()は初期設定で文字の列を自動では除かなくなりました。corr(numeric_only=True)を指定するか、数値の列だけを取り出してから計算しましょう。

ValueError: Unknown format code ‘d’ for object of type ‘float’

小数のデータ(相関係数など)にfmt="d"を指定すると出るエラーです。"d"は整数専用の書式なので、小数のデータにはfmt=".2f"などを使います。

ValueError: could not convert string to float: ‘Jan’

sns.heatmap(flights)のように、縦持ちのデータをそのまま渡すと出るエラーです。heatmapは表の中身をすべて数値として色にするので、月の名前などの文字が入っていると描けません。「データの準備」で紹介したように、pivotで横長の表にしてから渡しましょう。

日本語が「□」になる

エラーではなく「Glyph … missing from font(s) DejaVu Sans.」という警告が出て、日本語が「□」で表示されます。日本語フォントが指定されていないのが原因なので、前の章のようにplt.rcParams["font.family"]で日本語フォントを指定してください。

スポンサーリンク

まとめ

Seabornのheatmapを使うことで、表の形をしたデータの傾向や、項目どうしの相関を色で分かりやすく可視化することができます。ポイントをまとめると次のとおりです。

  • データはpivotなどで横長の表にしてから渡す
  • 数値を書き込むならannot=Trueと、データに合ったfmt(整数は"d"、小数は".2f")
  • 相関係数は発散型のcmapにvmin=-1, vmax=1, center=0をそろえて描く
  • maskで重複する半分を隠し、cbar_kwsやsquareで見た目を整える
  • 日本語を使うときはフォントを指定する

データ分析の最初の一歩として、相関行列のヒートマップを描いてデータの特徴をつかんでみましょう。

※本記事のコードは2026年10月31日時点で、Python 3.12.1、seaborn 0.13.2、matplotlib 3.11.2、pandas 3.1.0、numpy 2.5.4 の環境で動作を確認しています(参考:seaborn.heatmap 公式ドキュメント、pandas.DataFrame.corr 公式ドキュメント)。

タイトルとURLをコピーしました