5  可視化

表の数値を一つずつ読むだけでは,データの特徴をつかみにくいことがある.データをグラフで表すことを可視化(data visualization)という.

本章では,東京の降水量や気温,さくらの開花日を例に,目的に合ったグラフを選び,Python で描く方法を学ぶ.いずれも気象庁の観測データである.

知りたいこと 適したグラフ 本章の例
項目ごとの値を比べたい 棒グラフ 月ごとの降水量
時間とともに値がどう変わるかを見たい 折れ線グラフ 東京のさくらの開花日
どの範囲の値が多いかを知りたい ヒストグラム 日ごとの最高気温の分布

5.1 棒グラフ:雨の少ない月はどれか

棒グラフ(bar chart)は,項目ごとの値を棒の高さで表し,値の大小を比べるためのグラフである.チャプター 4 で使った東京の月ごとの気温と降水量の表から,降水量を比べてみよう.

tokyo_monthly.csv をダウンロードし,前章と同じ手順で Colab にアップロードする.本章のコードは,上から順に実行する.

import pandas as pd
import matplotlib.pyplot as plt

weather = pd.read_csv("tokyo_monthly.csv")
weather
month temp_mean_c precip_mm
0 1 6.6 26.0
1 2 6.5 6.5
2 3 10.7 153.0
3 4 15.6 154.5
4 5 19.2 206.0
5 6 24.7 100.0
6 7 28.4 74.5
7 8 29.6 68.5
8 9 26.5 203.5
9 10 18.5 106.5
10 11 12.8 17.0
11 12 8.4 36.5

グラフを描くには,Matplotlib というライブラリを使う.matplotlib.pyplot を plt という別名で読み込み,plt.bar() で棒グラフを描く.横軸には,month 列の 1 から 12 をそのまま使う.

plt.figure(figsize=(7, 4))
plt.bar(weather["month"], weather["precip_mm"], color="steelblue")
plt.axhline(100, color="black", linestyle="--", label="100 mm")
plt.xlabel("Month")
plt.ylabel("Precipitation (mm)")
plt.xticks(weather["month"])
plt.ylim(0, 250)
plt.legend()
plt.tight_layout()
plt.show()
1月26.0,2月6.5,3月153.0,4月154.5,5月206.0,6月100.0,7月74.5,8月68.5,9月203.5,10月106.5,11月17.0,12月36.5ミリメートルの棒グラフ.100ミリメートルの位置に水平の破線がある.
図 5.1: 東京の月ごとの降水量(2025 年).破線は 100 mm を表す.

図 5.1 では,100 mm を破線で示している.棒の上端が破線以下にある 1,2,6,7,8,11,12 月が,降水量が 100 mm 以下の月である.6 月はちょうど 100.0 mm なので,条件に含まれる.

コードの主な部分は,次の役割を持つ.

書き方 役割
plt.figure(figsize=(7, 4)) 幅 7 インチ,高さ 4 インチの図を用意する
plt.bar(項目, 値) 項目ごとの値を棒で表す
plt.axhline(100, ...) 縦軸の値が 100 の位置に水平線を引く
plt.xlabel(...),plt.ylabel(...) 横軸と縦軸に名前を付ける
plt.xticks(weather["month"]) 横軸の 1 から 12 の位置に目盛りを表示する
plt.ylim(0, 250) 縦軸の表示範囲を 0 から 250 にする
plt.legend() label で指定した説明を凡例として表示する
plt.tight_layout() 軸の名前などが図の外にはみ出しにくいように余白を調整する
plt.show() 図を表示する

棒グラフでは棒の高さを比較するため,縦軸は原則として 0 から始める.また,降水量なら「mm」,気温なら「℃」のように,数値の単位も軸に示そう.

5.2 折れ線グラフ:さくらの開花日は年によってどう変わるか

折れ線グラフ(line chart)は,時間などの順序に沿って点を線で結び,値の変化を表すグラフである.

気象庁は,1953 年から毎年,東京のソメイヨシノの開花日を観測している.セクション A.2.3 のデータから東京の開花日を取り出し,3 月 1 日を 1 日目として数えた日数に直した.例えば,3 月 24 日に開花した年は 24,4 月 1 日に開花した年は 32 となる.

range(1953, 2026) は,1953 以上 2026 未満の整数,つまり 1953 年から 2025 年までの年を表す.bloom_days には,各年の開花日を年の順に並べる.plt.plot() に横軸と縦軸の値を渡すと,折れ線グラフを描ける.marker="o" は,各観測値を丸い点で示す指定である.

years = range(1953, 2026)
bloom_days = [
    26, 26, 24, 26, 33, 30, 24,  # 1953〜1959 年
    23, 32, 32, 32, 33, 33, 20, 30, 29, 37,  # 1960〜1969 年
    38, 30, 28, 31, 33, 29, 22, 22, 31, 23,  # 1970〜1979 年
    31, 26, 23, 31, 42, 34, 34, 23, 33, 20,  # 1980〜1989 年
    20, 30, 24, 24, 31, 31, 31, 21, 27, 24,  # 1990〜1999 年
    30, 23, 16, 27, 18, 31, 21, 20, 22, 21,  # 2000〜2009 年
    22, 28, 31, 16, 25, 23, 21, 21, 17, 21,  # 2010〜2019 年
    14, 14, 20, 14, 29, 24,  # 2020〜2025 年
]

plt.figure(figsize=(7, 4))
plt.plot(years, bloom_days, marker="o", color="steelblue")
plt.xlabel("Year")
plt.ylabel("Bloom day (March 1 = 1)")
plt.ylim(0, 45)
plt.grid(axis="y", alpha=0.3)
plt.tight_layout()
plt.show()
1953年から2025年までの東京の開花日の折れ線グラフ.値は年によって14から42の間で大きく上下し,2000年ごろから低い値の年が多くなる.最も遅いのは1984年の42(4月11日),最も早いのは2020年,2021年,2023年の14(3月14日).
図 5.2: 東京のソメイヨシノの開花日(1953〜2025 年).縦軸は 3 月 1 日を 1 日目として数えた日数を表す.気象庁「生物季節観測累年値」を加工して作成.

plt.grid(axis="y", alpha=0.3) は,縦軸の目盛りに沿って薄い補助線を引く指定である.値を読み取るときの目安になる.

図 5.2 では,最も遅く開花したのは 1984 年の 4 月 11 日,最も早く開花したのは 2020 年,2021 年,2023 年の 3 月 14 日である.点を線で結ぶと,前の年より早くなったか,遅くなったかを追いやすい.開花日は年によって大きく上下するが,グラフ全体を見ると,最近の年ほど点が低い位置に多く,開花が早くなる傾向がうかがえる.

ただし,1 年分の変化だけで傾向を判断することはできない.例えば,2024 年の開花は前年より 15 日遅かったが,これだけで,開花が遅くなる傾向にあるとはいえない.また,開花が早くなった原因は,このグラフだけではわからない.原因を考えるには,気温など,ほかのデータも調べる必要がある.

月ごとの降水量の棒グラフも,横軸の月には時間の順序があった.このように,時間の順序がある項目でも,各項目の値の大小を比べたいときは棒グラフを使う.例えば,地理の授業で見た雨温図では,月ごとの降水量を棒グラフで,気温の変化を折れ線グラフで表している.何を知りたいかを考えて,グラフを選ぼう.

5.3 ヒストグラム:最高気温が何℃の日が多いか

今度は,日ごとの観測値を使って,分布を見てみよう.tokyo_daily.csv は,気象庁が東京で観測した 2025 年の日ごとの気温と降水量である.1 行が 1 日に対応し,各列は次の意味を持つ.

  • date:日付
  • month:月
  • temp_mean_c:平均気温(℃)
  • temp_max_c:最高気温(℃)
  • temp_min_c:最低気温(℃)
  • precip_mm:降水量(mm)

前章と同じ手順でアップロードしてから読み込む.365 日分の行があるため,head() で先頭の 5 行だけを表示する.

daily = pd.read_csv("tokyo_daily.csv")
daily.head()
date month temp_mean_c temp_max_c temp_min_c precip_mm
0 2025-01-01 1 7.1 12.2 4.1 0.0
1 2025-01-02 1 7.8 13.9 2.1 0.0
2 2025-01-03 1 5.5 7.6 3.7 0.0
3 2025-01-04 1 5.1 9.6 1.6 0.0
4 2025-01-05 1 4.6 10.0 -0.2 0.0

ヒストグラムには,この表から取り出した最高気温の列を使う.

daily_max = daily["temp_max_c"]

「最高気温が何℃くらいの日が多いか」「35℃ 以上の暑い日は何日あったか」を調べるには,値がどの範囲にどれだけ集まっているかを見るとよい.このような値の散らばり方を,データの分布という.

ヒストグラム(histogram)は,数値の範囲をいくつかの区間に分け,各区間に入るデータの個数を表すグラフである.区間を階級,その区間に入るデータの個数を度数という.本章では,すべての区間を同じ幅にして,棒の高さで度数を表す.

例えば,最高気温を 5℃ ごとの区間に分けると,日数は次のようになる.

最高気温の区間 日数
5℃ 以上 10℃ 未満 30
10℃ 以上 15℃ 未満 75
15℃ 以上 20℃ 未満 55
20℃ 以上 25℃ 未満 59
25℃ 以上 30℃ 未満 58
30℃ 以上 35℃ 未満 59
35℃ 以上 40℃ 以下 29

plt.hist() にデータを渡し,bins で区間の境界を指定する.

bins = [5, 10, 15, 20, 25, 30, 35, 40]

plt.figure(figsize=(7, 4))
plt.hist(daily_max, bins=bins, color="steelblue", edgecolor="white")
plt.xlabel("Maximum temperature (°C)")
plt.ylabel("Number of days")
plt.xticks(bins)
plt.tight_layout()
plt.show()
5以上10未満は30日,10以上15未満は75日,15以上20未満は55日,20以上25未満は59日,25以上30未満は58日,30以上35未満は59日,35以上40以下は29日.単位は℃.
図 5.3: 東京の日ごとの最高気温(2025 年の 365 日).区間の幅を 5℃ にしたヒストグラム.

bins=[5, 10, 15, 20, 25, 30, 35, 40] は,7 個の区間の境界を指定している.plt.xticks(bins) は,その境界の位置に横軸の目盛りを表示する指定であり,区間そのものを決めるものではない.

plt.hist() では,各区間は左端を含み,右端を含まない.ただし,最後の区間だけは右端も含む.例えば,最高気温がちょうど 35.0℃ の日は「30℃ 以上 35℃ 未満」ではなく,「35℃ 以上 40℃ 以下」に数える.

図 5.3 から,10℃ 以上 15℃ 未満の日が 75 日と最も多いことがわかる.その多くは,12 月から 2 月の冬の日である.一方,15℃ 以上 35℃ 未満の四つの区間の日数は 55 日から 59 日で,大きな差はない.また,最高気温が 35℃ 以上の日も 29 日あった.最も多い区間だけでなく,分布全体の形にも注目しよう.

5.3.1 棒グラフとの違い

月ごとの降水量を示す棒グラフでは,横軸に月,縦軸に降水量をとった.ヒストグラムでは,横軸に最高気温の区間,縦軸にその区間に入る日数をとる.棒が高いほど気温が高いのではなく,その区間に入る日が多い.

また,ヒストグラムの横軸は数値の大小を表すため,区間を好きな順に並べ替えることはできない.隣り合う区間が連続していることがわかるように,棒の間を空けずに描く.

5.3.2 区間の幅によって見え方が変わる

同じデータでも,区間を広くすると細かな違いが見えにくくなり,狭くすると一つ一つの値の違いが目立つ.特にデータが少ない場合,細かく分けすぎると全体の傾向をつかみにくい.

ヒストグラムを読むときは,区間の幅とデータの個数も確認しよう.練習問題では,同じ最高気温のデータを 2℃ ごとの区間に分け,見え方を比べる.

5.4 練習問題

練習 5.1 次のリストは,2021 年から 2025 年までの東京の猛暑日(最高気温が 35℃ 以上の日)の日数である.気象庁の観測データから数えた.このデータを棒グラフにせよ.縦軸の 20 日の位置に水平線を加え,猛暑日が 20 日以上だった年を答えよ.

years = [2021, 2022, 2023, 2024, 2025]
hot_days = [2, 16, 22, 20, 29]

練習 5.2 スマートフォンを充電せずに使い続けたとき,バッテリー残量を 1 時間ごとに記録したとする.以下のデータを折れ線グラフにし,残量が最も大きく減った時間帯を答えよ.

hours = [9, 10, 11, 12, 13, 14, 15]
battery = [100, 92, 83, 64, 55, 37, 28]

練習 5.3 日ごとの最高気温 daily_max を使い,区間の幅を 2℃ にしたヒストグラムを描け.区間の境界は,次の bins とする.

bins = [4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40]
  1. 日数が最も多い区間を答えよ.
  2. 図 5.3 と比べ,見え方がどのように変わったか説明せよ.

練習 5.4 歩数,飲み物の価格,通学時間など,身近なデータを一つ選び,グラフを作成せよ.データの出典または記録した期間を示し,次の点を説明せよ.

  1. 何を知るために,その種類のグラフを選んだか.
  2. グラフから何がわかるか.

5.5 まとめ

  • 項目ごとの値を比べるには棒グラフ,時間に沿った変化を見るには折れ線グラフ,値の分布を見るにはヒストグラムが適している.
  • ヒストグラムの見え方は,区間の幅によって変わる.
  • グラフには軸の名前と単位を示し,データから読み取れることを言葉でも説明する.

次章からは,平均値や中央値,ばらつきを表す数値を学ぶ.中央値と四分位数で分布を要約する箱ひげ図は,四分位数と四分位範囲を学んだ後に セクション 7.2 で扱う.

ヒントヒストグラムの設定を調べる

色や区間の指定についてさらに調べたい場合は,Matplotlib の hist() の公式ドキュメントを参照するとよい.