学習コースLearn
データ可視化
データを正しく、そしてわかりやすく伝えるための図の作り方を、概要から原則、そして実際に動かせるコードまで、順を追って学ぶモジュールです。各ステップは「概要 → 仕組み(座学)→ コードで動かす」の3層で進みます。ページ内には手を動かせるデモを3つ用意しました。
この教材は日本語のみで提供していますThis learning material is available in Japanese only.
はじめにIntroduction
このモジュールの全体像
データ可視化(data visualization)とは、数値や表のままでは見えにくいデータの構造や傾向を、図やグラフの形にして目で読み取れるようにする技術です。データを自分で理解するための探索的な可視化と、わかったことを他者に伝えるための説明的な可視化の、両方の場面で使われます。
良い図はただ数値をきれいに飾るものではありません。伝えたいことを正確に、そして誤解なく届けるための道具です。そのために、多くの図づくりに共通する次のような流れ(考え方の順序)があります。伝えたいことに合わせて図を選び、軸や色を設計し、余計な装飾を削り、読み手に伝わる形へ仕上げます。
データ可視化の基本的な流れ
このモジュールは、上の流れに沿って進みます。各ステップは次の3層で構成します。
- 概要:その考え方や道具が何のためにあるのか、あらましをつかむ。
- 仕組み(座学):背後にある原則・定義を、ていねいに理解する。
- コードで動かす:Python の定番ライブラリや、ページ内デモで実際に動かして確かめる。
手を動かす題材には、実在の公開データセット(seaborn に同梱の tips や penguins など)や、ページ内の小さなサンプルだけを使います。特別な環境がなくても、読みながら試せる構成です。
データ可視化とは
Why we visualize概要Overview
データ可視化は、数値や表を図の形にして「目で読み取れる」ようにする技術です。私たちは次のような場面で、すでにその成果に触れています。
- 探索:手元のデータにどんな傾向や外れ値があるかを、自分の目で確かめる。
- 報告:分析でわかったことを、資料や論文の図として他者に伝える。
- 比較:グループごとの違いや、時間による変化を一目で見比べる。
- 監視:売上や気温などの指標を、ダッシュボードで継続的に見守る。
可視化の目的は大きく2つに分けられます。データを理解するための探索的可視化(exploratory)と、わかったことを伝えるための説明的可視化(explanatory)です。前者は自分のための素早い図でよく、後者は読み手に配慮した丁寧な図が求められます。
仕組みHow it works
そもそも、なぜ図にするのでしょうか。平均や分散などの要約統計だけでは、データの姿は見えないからです。これを鮮やかに示すのがアンスコムの例(Anscombe's quartet)です。統計学者フランク・アンスコムが1973年に示した、4つのデータの組です。
- 4つの組は、平均・分散・相関係数・回帰直線がほぼ同じになるように作られています。数値の要約だけを見ると、4つは「同じデータ」に見えます。
- ところが散布図を描くと、ある組はきれいな直線、ある組は曲線、ある組は1つの外れ値に引っ張られた形と、まったく違う姿が現れます。
同じ主旨の、より新しい例に「Datasaurus(データサウルス)」もあります。要約統計はそっくりなのに、点を描くと恐竜の絵になるデータです。いずれも「まず図を描く」ことの大切さを教えてくれます。図は、要約された数値が捨ててしまう分布の形・外れ値・関係のかたちを目に見せてくれるのです。
このモジュールでは、Step 2 で図の選び方を、Step 3 で良い図の原則を学び、Step 4・5 で matplotlib と seaborn による実装を、Step 6 で誤解を招く図の避け方を扱います。
この Step のまとめ
データ可視化は、要約統計だけでは見えないデータの姿を目で読み取れるようにする技術です。目的は「自分が理解するため(探索的)」と「他者に伝えるため(説明的)」の2つ。アンスコムの例が示すように、まず図を描く習慣が分析の第一歩です。
図の種類と選び方
Choosing the right chart概要Overview
図づくりの最初の分かれ道は「どの図を使うか」です。図の種類は、見た目の好みではなく伝えたいこと(目的)とデータの型から決めます。目的に合わない図を選ぶと、正しいデータでも読み手に伝わりません。まずは代表的な5つの目的と、それに対応する図を押さえましょう。
仕組みHow it works
1. 比較:棒グラフ
カテゴリごとの量を比べるなら棒グラフです。長さで大小を読むので、必ず0を起点にします。項目が多いときは横棒にすると項目名が読みやすくなります。
2. 推移:折れ線グラフ
時間にそった変化を見るなら折れ線グラフです。連続した時間を線でつなぎます。順序のないカテゴリを線で結ぶのは誤りです。折れ線は変化の傾きが主役なので、0起点は必須ではありません。
3. 分布:ヒストグラム・箱ひげ図・バイオリンプロット
1つの数値変数がどう散らばっているかを見るならヒストグラムです。値を区間(ビン)に区切って本数を数えます。ビン幅で印象が変わる点に注意します。複数の群を比べるなら、箱ひげ図(中央値・四分位・外れ値)やバイオリンプロット(分布の形も見える)が便利です。
4. 関係:散布図
2つの数値変数の関係を見るなら散布図です。点の広がりから、相関の向きや強さ、外れ値が読み取れます。点が重なるときは透明度やサイズを調整します。
5. 割合:円グラフには注意
全体に対する内訳を示すのが割合です。円グラフは有名ですが、人は角度や面積の比較が苦手なので、項目が2〜3個までに留めます。項目が多いときや正確な比較には、棒グラフ(必要なら積み上げ棒)のほうが読みやすくなります。
図の選び方ガイド
伝えたい目的と、手元のデータの型を選ぶと、おすすめの図と注意点を表示します。小さなサムネイルで図の形もイメージできます。目的とデータの型がかみ合っているかも判定します。
コードで動かすRun the code
matplotlib では、目的に応じて呼ぶメソッドを変えるだけです。まず比較の棒グラフ。0起点を保つよう set_ylim の下限を0にします。
import matplotlib.pyplot as plt
categories = ["A", "B", "C", "D"]
values = [23, 45, 17, 31]
fig, ax = plt.subplots()
ax.bar(categories, values)
ax.set_ylabel("count")
ax.set_ylim(0, 50) # 棒グラフは必ず0起点
plt.show()
# A〜D の高さ 23・45・17・31 の棒グラフが表示される
# 縦軸は 0 から 50 まで(0起点なので大小が正しく読める)推移は折れ線、関係は散布図です。同じ ax に対してメソッドを変えるだけで描き分けられます。
import matplotlib.pyplot as plt
# 推移: 折れ線グラフ(横軸は時間の順序)
years = [2019, 2020, 2021, 2022, 2023]
sales = [120, 135, 128, 150, 162]
fig, ax = plt.subplots()
ax.plot(years, sales, marker="o")
ax.set_xlabel("year")
ax.set_ylabel("sales")
plt.show()
# 関係: 散布図
x = [1.2, 2.4, 3.1, 4.6, 5.0]
y = [2.1, 3.9, 6.2, 7.8, 9.9]
fig, ax = plt.subplots()
ax.scatter(x, y)
plt.show()
# 折れ線: 2019→2023 の売上の推移が右上がりの線で表示される
# 散布図: x と y の点が右上がりに並ぶ(正の関係)この Step のまとめ
図は「目的(比較・推移・分布・関係・割合)」と「データの型」から選びます。比較は棒、推移は折れ線、分布はヒストグラムや箱ひげ、関係は散布図、割合は棒(円は控えめに)。デモで組み合わせを試すと、対応関係が体になじみます。
良い図の原則
Principles of good figures概要Overview
図の種類を選んだら、次は「わかりやすく、正直に」仕上げます。ここには昔から語られてきた原則があります。中心にあるのは、読み手が最小の労力で正しく読み取れることです。飾りではなく、伝えることを優先します。
仕組みHow it works
データインク比(data-ink ratio)
統計グラフィックスの古典を書いたエドワード・タフテ(Edward Tufte)は、図に使うインクのうち「データそのものを表す割合」をデータインク比と呼びました。狙いは、この比を高めること。背景の濃い色、余計な枠線、意味のない3D、目盛りの過剰な装飾(chartjunk)を削り、データに注意を集めます。
明快さ第一
図はパズルではありません。タイトル・軸ラベル・単位を明記し、凡例は該当する要素の近くに置きます。要素が少なければ、凡例の代わりに線や棒へ直接ラベルを添えるほうが読みやすいこともあります。
軸の扱い
もっとも誤解を生みやすいのが軸です。棒グラフは必ず0を起点にします。棒は長さで量を表すため、途中で切ると差が誇張されてしまうからです(次のデモで体験します)。折れ線は変化の傾きを見るので、0起点は必須ではありませんが、起点は明示します。二重軸(左右で別スケール)は誤解のもとになりやすく、慎重に使います。
色の使い方と色覚多様性
色は意味を持たせて使い、数を絞ります。赤と緑だけで区別するのは、色覚の多様性を考えると避けたい配色です。色に加えて形やラベルでも区別できるようにし、連続量には viridis のような色覚に配慮したカラーマップを使うと安全です。
誤解を招く図 vs 正直な図
まったく同じ4つの値の棒グラフです。y軸の起点を「0から」と「値の近くで切る」で切り替えると、棒の見え方がどれだけ変わるかがわかります。データは同じでも、軸の切り詰めだけで差を何倍にも誇張できてしまいます。
コードで動かすRun the code
matplotlib で「装飾を削る」のは、余分な枠線(spines)を消し、目盛りを整え、0起点を保つといった小さな積み重ねです。デフォルトの図から、データに注意が向く図へ整えます。
import matplotlib.pyplot as plt
categories = ["A", "B", "C", "D"]
values = [48, 50, 53, 55]
fig, ax = plt.subplots()
ax.bar(categories, values, color="#0E6F5C")
# 余計な装飾を削る(データインク比を上げる)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.set_ylim(0, 60) # 棒グラフは0起点を保つ
ax.set_ylabel("score")
ax.set_title("scores by group")
plt.show()
# 上と右の枠線が消え、0起点の棒グラフが表示される
# 4本の高さ 48・50・53・55 の差は「わずか」であることが正しく伝わる色覚に配慮した連続カラーマップを使うのも簡単です。散布図の点を数値で色分けするときは、既定の色ではなく viridis を指定します。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [2, 3, 5, 4, 6]
z = [10, 30, 50, 70, 90] # 色で表す量
fig, ax = plt.subplots()
sc = ax.scatter(x, y, c=z, cmap="viridis")
fig.colorbar(sc, label="value") # 凡例としてカラーバー
plt.show()
# 点が z の値に応じて viridis の色(紫→黄)で塗り分けられ、
# 右側に色と値の対応を示すカラーバーが表示されるこの Step のまとめ
良い図は「データインク比を高め、明快に、正直に」。とくに棒グラフは0起点が鉄則です。色は数を絞り、赤緑だけに頼らず、連続量には色覚に配慮したカラーマップを使います。デモで軸の切り詰めの威力を確かめてください。
matplotlib の基礎
matplotlib basics概要Overview
Python で図を描くときの土台になるのが matplotlib です。seaborn や pandas の作図も、内部では matplotlib を使っています。まずはその基本的な組み立て方を押さえると、あらゆる図を細かく調整できるようになります。
仕組みHow it works
figure と axes
matplotlib の図は、2つの入れ物でできています。figure(図全体のキャンバス)と、その中に置かれる axes(1枚1枚の描画領域)です。fig, ax = plt.subplots() と書くと、figure と1つの axes をまとめて作れます。以降は ax に対して ax.plot() や ax.bar() を呼んで描き、ax.set_xlabel() などで飾ります。この「オブジェクト指向スタイル」は、複数の図を扱うときに見通しがよく、おすすめです。
軸・目盛・凡例・注釈
図の意味は、周辺の情報で決まります。よく使う設定は次のとおりです。
- 軸ラベル・タイトル:
ax.set_xlabel/ax.set_ylabel/ax.set_title。 - 範囲:
ax.set_xlim/ax.set_ylim(棒グラフは下限を0に)。 - 凡例:各プロットに
label=を付け、ax.legend()を呼ぶ。 - 注釈:特定の点に説明を添える
ax.annotate("text", xy=(x, y))。
複数図(subplots)
1枚の figure に複数の axes を並べたいときは plt.subplots(nrows, ncols) を使います。返ってくる axes は配列で、axes[0], axes[1] のように個別に描けます。並べて比べる図(スモールマルチプル)に便利です。
日本語表示の注意
matplotlib の既定フォントは日本語を含まないため、そのままだと日本語ラベルが豆腐(□)になります。日本語を表示するには、日本語フォントを設定するか、japanize-matplotlib のような補助ライブラリを使います。plt.rcParams["font.family"] に手元の日本語フォント名を指定するのが基本です。
コードで動かすRun the code
まずは figure と axes を作り、折れ線を描いて、ラベル・凡例・注釈まで付ける基本形です。
import matplotlib.pyplot as plt
x = [0, 1, 2, 3, 4]
y = [1, 3, 2, 5, 4]
fig, ax = plt.subplots(figsize=(6, 4))
ax.plot(x, y, marker="o", label="series 1")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_title("a simple line plot")
ax.legend() # label を凡例として表示
ax.annotate("peak", xy=(3, 5), # 点に注釈
xytext=(3.2, 4.2))
plt.show()
# タイトル・軸ラベル・凡例・注釈つきの折れ線グラフが1枚表示される複数の図を横に並べるには subplots の行数・列数を指定します。返り値の axes を個別に扱います。
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(9, 4))
axes[0].bar(["A", "B", "C"], [3, 5, 2])
axes[0].set_title("bar")
axes[1].plot([1, 2, 3], [2, 1, 3])
axes[1].set_title("line")
fig.tight_layout() # 余白を自動調整
plt.show()
# 左に棒グラフ、右に折れ線グラフが横並びで表示される日本語ラベルを使うなら、フォントの設定が要ります。手元に入っている日本語フォント名を指定します。
import matplotlib.pyplot as plt
# 手元の日本語フォントを指定(例: IPAexGothic / Noto Sans CJK JP)
plt.rcParams["font.family"] = "IPAexGothic"
fig, ax = plt.subplots()
ax.bar(["りんご", "みかん", "ぶどう"], [5, 3, 4])
ax.set_ylabel("個数")
plt.show()
# japanize_matplotlib を import するだけで済ませる方法もある
# 軸ラベルや項目名が日本語で正しく表示される(□にならない)この Step のまとめ
matplotlib は figure(キャンバス)と axes(描画領域)の2階層。fig, ax = plt.subplots() から始め、ax に描いてラベル・凡例・注釈で仕上げます。日本語はフォント設定が必要です。この土台の上に、次の seaborn が乗ります。
seaborn で統計的可視化
Statistical graphics with seaborn概要Overview
seaborn は matplotlib の上に作られた、統計的な可視化に特化したライブラリです。分布・関係・カテゴリの比較といった「よくある図」を、短いコードで、見栄えよく描けます。pandas のデータフレームと相性がよく、列名を指定するだけで図になります。
仕組みHow it works
分布を見る
1つの数値変数の散らばりは histplot(ヒストグラム)や kdeplot(カーネル密度推定でなめらかな分布曲線)で見ます。hue にカテゴリ列を渡すと、群ごとに色を分けて重ねられます。
関係を見る
2つの数値変数の関係は scatterplot(散布図)です。傾向線も一緒に見たいときは regplot を使うと、散布図に回帰直線と信頼区間の帯を重ねてくれます。
カテゴリで比べる
群ごとの分布を比べるには boxplot(箱ひげ図)や violinplot(分布の形も見える)が便利です。中央値・四分位・外れ値や、山の形の違いが一目で分かります。
相関を俯瞰する
多くの変数の相関を一望するには、相関行列を heatmap で色分けします。annot=True で数値も重ねられます。
ファセット(小さな図の並び)
カテゴリごとに同じ図を並べて比べたいときは relplot や FacetGrid を使い、col= や row= に列名を渡します。seaborn には練習用の実在データが同梱されており、sns.load_dataset("tips") や sns.load_dataset("penguins") ですぐ読み込めます。
散布図と相関
点を追加したりプリセットを選ぶと、ピアソンの相関係数と最小二乗法による回帰直線をその場で計算し、SVGで描きます。図の上でクリックすると点を足せます。相関の強さが、点の散らばり(視覚)と数値でどう対応するかを確かめてください。
コードで動かすRun the code
まずは同梱データ tips(レストランの会計と心づけ)で、散布図に回帰直線を重ねます。列名を渡すだけです。
# pip install seaborn
import seaborn as sns
import matplotlib.pyplot as plt
tips = sns.load_dataset("tips") # 実在の同梱データ
# 会計額と心づけの関係を、回帰直線つきで見る
sns.regplot(data=tips, x="total_bill", y="tip")
plt.show()
# 相関係数(ピアソン)を数値でも確認
print(tips["total_bill"].corr(tips["tip"]).round(3))
# 会計額(x)と心づけ(y)の散布図に、右上がりの回帰直線と帯が重なる
0.676分布とカテゴリ比較も一行です。penguins(3種のペンギンの計測データ)で、種ごとの分布を箱ひげ図とヒストグラムにします。
import seaborn as sns
import matplotlib.pyplot as plt
pen = sns.load_dataset("penguins")
# 種ごとに、くちばしの長さの分布を箱ひげ図で比較
sns.boxplot(data=pen, x="species", y="bill_length_mm")
plt.show()
# 種ごとに色を分けたヒストグラム(分布を重ねて表示)
sns.histplot(data=pen, x="flipper_length_mm", hue="species")
plt.show()
# 箱ひげ図: 3種のくちばし長の中央値・四分位・外れ値が並ぶ
# ヒストグラム: 種ごとに色分けされたひれ長の分布が重なって表示される数値列どうしの相関をまとめて見るなら、相関行列をヒートマップにします。tips の数値列で試します。
import seaborn as sns
import matplotlib.pyplot as plt
tips = sns.load_dataset("tips")
corr = tips[["total_bill", "tip", "size"]].corr()
sns.heatmap(corr, annot=True, cmap="viridis", vmin=0, vmax=1)
plt.show()
# 3x3 の相関行列がヒートマップで表示される(対角は 1.00)
# total_bill と tip の相関 0.68 などがマスに数値つきで色分けされるこの Step のまとめ
seaborn は「よくある統計の図」を短く描く道具。分布は histplot/kdeplot、関係は scatterplot/regplot、カテゴリ比較は boxplot/violinplot、相関一覧は heatmap、並べるなら relplot。同梱の tips・penguins ですぐ試せます。
誤解を招く図を避ける
Avoiding misleading charts概要Overview
可視化は強力ですが、その力は誤用もできてしまいます。正しいデータでも、図の作り方次第で読み手を誤らせられるのです。悪意がなくても、うっかり誤解を招く図を作ってしまうことは珍しくありません。ここでは、典型的な落とし穴を知り、自分の図を点検できるようにします。
仕組みHow it works
1. 軸の操作
もっとも多いのが軸の細工です。棒グラフのy軸を0以外から始めると、わずかな差が何倍にも見えます(Step 3のデモで体験したとおりです)。逆に、変化を小さく見せたいときに軸を極端に広げることもあります。折れ線でも、縦軸の範囲しだいで傾きの印象は大きく変わります。
2. チェリーピッキング
都合のよい期間や対象だけを選んで見せる手口です。上昇に転じた月からグラフを始める、外れ値を黙って除く、といった切り取りで、全体像とは違う印象を与えます。図の「範囲」そのものを疑う視点が大切です。
3. 3Dの乱用と面積・体積の誤用
立体的な棒グラフや円グラフは、奥行きによって手前が大きく見え、正確な比較を妨げます。また、値を円や図形の面積・体積で表すとき、直径や辺の長さを値に比例させてしまうと、面積は2乗・体積は3乗で効くため、差が過大に見えます。長さで比べられる棒グラフのほうが安全です。
4. 二重軸の罠
左右で別々のスケールを持つ二重軸は、2本の線の交差や上下関係を、目盛りの取り方しだいで自由に演出できてしまいます。「相関しているように見せる」ための道具になりやすく、使うなら目盛りの根拠を明確にします。
5. 相関の見せかけ
2つの量が一緒に動いていても、それは偶然の一致や、背後の第三の要因によることがあります(見せかけの相関、擬似相関)。相関は因果を意味しません。散布図で強い関係が見えても、「だから一方が他方の原因だ」と結論づけないよう注意します。
この Step のまとめ
誤解を招く図の典型は、軸の操作・チェリーピッキング・3Dや面積の誤用・二重軸・見せかけの相関。作る側としてはこれらを避け、読む側としては「軸の起点」「範囲」「相関と因果」を疑う目を持つこと。これが正直な可視化の土台です。
まとめWrap-up
学びの振り返りと、さらに学ぶために
このモジュールでは、データを図にして正しく伝えるための考え方と道具を、順に手に入れました。
- 可視化とは:要約統計だけでは見えないデータの姿を、図で読み取る(探索的と説明的)。
- 図の選び方:目的(比較・推移・分布・関係・割合)とデータの型から図を選ぶ。
- 良い図の原則:データインク比を高め、棒グラフは0起点、色は色覚に配慮する。
- 実装:matplotlib で土台を組み、seaborn で統計の図を短く描く。
- 誤解を避ける:軸の操作・チェリーピッキング・二重軸・見せかけの相関に注意する。
次に進むなら、下の道具と資料が役に立ちます。
公開データセット
- tips:レストランの会計と心づけ。seaborn に同梱(
load_dataset("tips"))。 - penguins:3種のペンギンの計測データ。seaborn 同梱。
- flights:月別の航空旅客数。seaborn 同梱で時系列やヒートマップの練習に。
ライブラリ
- matplotlib:Python の作図の土台。
- seaborn:統計的可視化を短く。
- plotly:インタラクティブな可視化。
- pandas.plot:データフレームから直接作図。
参考書
- Edward Tufte『The Visual Display of Quantitative Information』
- Alberto Cairo『The Truthful Art』
- 永田ゆかり『データ視覚化のデザイン』
おつかれさまでした
ここで学んだ「目的から図を選び、正直に設計する」という流れは、あらゆるデータを扱う場面で共通の考え方です。手元のサンプルを書き換えて、3 つのデモをもう一度動かしてみてください。図の見え方がどう変わるかを確かめると、理解がぐっと深まります。
発展トピックBeyond this module
このコースでは扱わない、関係する発展トピック
このモジュールでは、matplotlib と seaborn による静的な図づくりの「基礎の流れ」を扱いました。いっぽうで近年の可視化は、対話的な操作や地図・大規模データ・ウェブ表現へと広がっています。ここでは、このコースでは踏み込まないものの、知っておくと視野が広がる発展的なトピックを、特に近年の主流を中心に紹介します。深掘りは各自の興味に合わせてどうぞ。
インタラクティブ可視化
- Plotly・Bokeh:ズームやホバーで詳細を見られる対話的な図をブラウザ上で描く。
- Altair:可視化文法(Vega-Lite)にもとづき、宣言的に図を組み立てるライブラリ。
地理空間とダッシュボード
- 地理空間可視化:地図上にデータを重ねる(GeoPandas など)。
- ダッシュボード:指標を継続的に見せるアプリを作る(Streamlit・Dash)。
大規模データとネットワーク
- 大規模データの可視化:数百万点を集約して描く(datashader)。
- ネットワーク可視化:ノードとエッジのつながりを図にする(別途ネットワーク分析の話題)。
色理論とウェブ表現
- 色理論とアクセシビリティ:色覚多様性に配慮した配色や、知覚的に均等なカラーマップの設計。
- D3.js:ウェブ上で自由度の高い可視化を作るための JavaScript ライブラリ。