データは私たちの周りに溢れていますが、その意味を理解するには可視化が欠かせません。
Pythonの強力なライブラリ、matplotlibを使えば、複雑なデータでも美しく分かりやすいグラフに変換できます。
今回は、matplotlibの基礎からステップバイステップで解説します。
誰もがデータの物語を視覚的に語れるようになるでしょう。
Contents
はじめに
データ可視化の重要性
私たちは日々、膨大な量のデータに囲まれています。ビジネス、科学研究、社会現象など、あらゆる分野でデータが生成され、蓄積されています。
しかし、生のデータだけでは、その中に隠れている重要な洞察や傾向を見出すのは困難です。ここで力を発揮するのが、データ可視化です。
データ可視化は、複雑なデータセットを視覚的に表現することで、以下のような利点をもたらします。
- 傾向や異常値の素早い発見
- 複雑な概念やアイデアの効果的な伝達
- データ間の関係性の理解促進
- 意思決定プロセスの支援
適切に設計されたグラフや図表は、数千行のデータを一目で理解可能にし、重要な情報を即座に伝えることができます。
Pythonとmatplotlibの簡単な紹介
データ可視化を行うためのツールは多数存在しますが、その中でもPythonは特に人気があります。
Pythonは、その簡潔な文法と豊富なライブラリのエコシステムにより、データ分析や機械学習の分野で広く使用されています。
Pythonのデータ可視化ライブラリの中で、最も基本的かつ強力なものの一つが「matplotlib」です。matplotlibは以下のような特徴を持っています。
- 多様なグラフタイプ:折れ線グラフ、棒グラフ、散布図、ヒストグラムなど、様々な種類のグラフを作成できます。
- 高度なカスタマイズ性:色、スタイル、レイアウトなど、グラフの細部まで調整可能です。
- 他のライブラリとの連携:NumPy、Pandasなど、他のPythonライブラリとシームレスに連携できます。
- 出力形式の多様性:PNG、PDF、SVGなど、様々な形式で保存できます。
matplotlibは1999年にJohn Hunterによって開発が始まり、現在も活発にメンテナンスされています。
その使いやすさと柔軟性から、データサイエンティストや研究者、エンジニアなど、幅広いユーザーに支持されています。
matplotlibのセットアップ
インストール方法
matplotlibは、Pythonのパッケージ管理ツールであるpipを使用して簡単にインストールできます。
以下のコマンドをターミナルまたはコマンドプロンプトで実行してください。
pip install matplotlib pip install japanize-matplotlib #日本語表示させたいときに必要
基本的な設定
matplotlibをインポートし、基本的な設定を行うには、以下のようなコードを使用します。
import matplotlib.pyplot as plt
import japanize_matplotlib
import numpy as np
# グラフのスタイルを設定
plt.style.use('seaborn-v0_8-darkgrid')
# 日本語フォントの設定(必要な場合)
plt.rcParams['font.family'] = 'IPAexGothic'
# グラフのサイズを設定
plt.figure(figsize=(10, 6))
# サンプルデータの作成
x = np.linspace(0, 10, 100)
y = np.sin(x)
# プロットの作成
plt.plot(x, y)
plt.title('サイン波')
plt.xlabel('x')
plt.ylabel('sin(x)')
# グラフの表示
plt.show()
このコードについて説明します。
matplotlib.pyplotをpltとしてインポートします。pltは慣例的なもので、別名として利用できます。japanize_matplotlibは、グラフ内で日本語を利用するときに必要になります。numpyもnpとしてインポートします。数値計算に使用します。plt.style.use('seaborn-v0_8-darkgrid')でグラフのスタイルを設定します。seabornは見やすいスタイルの一つです。- 日本語フォントを使用する場合は、
plt.rcParams['font.family']で設定します。 plt.figure(figsize=(10, 6))でグラフのサイズを設定します。- サンプルデータとしてサイン波を作成し、プロットします。
- タイトルと軸ラベルを設定します。
plt.show()でグラフを表示します。
このコードを実行すると、以下のようなシンプルなサイン波のグラフが表示されます。

Figureとaxesの基礎
FigureとAxesとは?
Figureは、グラフ全体を表す最上位のコンテナです。1つのFigureは、1つまたは複数のAxes(サブプロット)を含むことができます。

Axesは、実際にデータをプロットする領域です。x軸とy軸を持ち、これらの軸上にデータポイントやラインがプロットされます。1つのFigureは複数のAxesを持つことができます。
以下に、FigureとAxesを明示的に使用するコード例を示します。
import matplotlib.pyplot as plt
import numpy as np
# データの生成
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
# Figureの作成
fig = plt.figure(figsize=(12, 6))
# Axesの追加
ax1 = fig.add_subplot(121) # 1行2列の1番目
ax2 = fig.add_subplot(122) # 1行2列の2番目
# 各Axesにプロット
ax1.plot(x, y1)
ax1.set_title('sin(x)')
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax2.plot(x, y2)
ax2.set_title('cos(x)')
ax2.set_xlabel('x')
ax2.set_ylabel('y')
# 全体のタイトル
fig.suptitle('Sin and Cos Functions', fontsize=16)
plt.tight_layout()
plt.show()
このコードでは以下のことを行っています。
plt.figure()でFigureオブジェクトを作成します。fig.add_subplot()でAxesオブジェクトを作成し、Figureに追加します。- 各Axesオブジェクト(
ax1とax2)に対してプロットやカスタマイズを行います。 fig.suptitle()でFigure全体のタイトルを設定します。
以下、実行結果です。

シンプルな使用方法:単一のAxes
1つのFigureに1つのAxesのみを使用する場合、明示的にAxesを追加する必要はありません。
このような場合、より簡潔な方法でグラフを作成できます。
以下、コードです。
import matplotlib.pyplot as plt
import numpy as np
# データの生成
x = np.linspace(0, 10, 100)
y = np.sin(x)
# プロットの作成
plt.figure(figsize=(10, 6))
plt.plot(x, y)
plt.title('Sin Function')
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.show()
このコードでは、以下のようなシンプルな流れでグラフを作成しています。
plt.figure()でFigureを作成します。plt.plot()で直接データをプロットします。この時、暗黙的に1つのAxesが作成されます。plt.title(),plt.xlabel(),plt.ylabel()などの関数で、暗黙的に作成されたAxesの属性を設定します。
以下、実行結果です。

この方法は、単一のグラフを素早く作成する際に非常に便利です。コードがシンプルになり、可読性も高くなります。
ただし、より複雑なカスタマイズや複数のサブプロットを作成する場合は、明示的にFigureとAxesを操作する方が柔軟性が高くなります。
基本的なプロット作成
折れ線グラフ
折れ線グラフは、連続的なデータの変化を表現するのに適しています。時系列データの可視化によく使用されます。
以下は、簡単な折れ線グラフを作成するコードです。
import matplotlib.pyplot as plt
import japanize_matplotlib
import numpy as np
# データの生成
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
# プロットの作成
plt.figure(figsize=(10, 6))
plt.plot(x, y1, label='sin(x)')
plt.plot(x, y2, label='cos(x)')
# グラフの設定
plt.title('正弦波と余弦波')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.grid(True)
# グラフの表示
plt.show()
このコードは、sin関数とcos関数のグラフを同一の座標系に描画します。
plt.legend()で凡例を追加し、plt.grid(True)でグリッド線を表示しています。
以下、実行結果です。

棒グラフ
棒グラフは、カテゴリカルデータの比較や、離散的な値の表現に適しています。
以下は、簡単な棒グラフを作成するコードです。
import matplotlib.pyplot as plt
import japanize_matplotlib
import numpy as np
# データの準備
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 35, 14, 28, 39]
# プロットの作成
plt.figure(figsize=(10, 6))
plt.bar(categories, values)
# グラフの設定
plt.title('カテゴリ別の値')
plt.xlabel('カテゴリ')
plt.ylabel('値')
# 棒の上に値を表示
for i, v in enumerate(values):
plt.text(i, v, str(v), ha='center', va='bottom')
# グラフの表示
plt.show()
このコードは、5つのカテゴリとそれぞれの値を棒グラフで表現しています。
plt.text()を使用して、各棒の上に値を表示しています。
以下、実行結果です。

散布図
散布図は、2つの変数間の関係を可視化するのに適しています。相関関係の分析によく使用されます。
以下は、簡単な散布図を作成するコードです。
import matplotlib.pyplot as plt
import japanize_matplotlib
import numpy as np
# データの生成
np.random.seed(0)
x = np.random.randn(100)
y = 2 * x + np.random.randn(100) * 0.5
# プロットの作成
plt.figure(figsize=(10, 6))
plt.scatter(x, y, alpha=0.5)
# グラフの設定
plt.title('散布図の例')
plt.xlabel('x')
plt.ylabel('y')
# 回帰直線の追加
z = np.polyfit(x, y, 1)
p = np.poly1d(z)
plt.plot(x, p(x), "r--")
# グラフの表示
plt.show()
このコードは、ランダムに生成したデータポイントを散布図で表現し、さらに回帰直線を追加しています。
alpha=0.5でポイントの透明度を設定し、重なりを視覚化しています。
以下、実行結果です。

グラフのカスタマイズ
タイトルと軸ラベルの追加
グラフにタイトルや軸ラベルを追加することで、データの内容をより明確に伝えることができます。
import matplotlib.pyplot as plt
import japanize_matplotlib
import numpy as np
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.figure(figsize=(10, 6))
plt.plot(x, y)
plt.title('正弦波のグラフ', fontsize=20, fontweight='bold')
plt.xlabel('時間 (秒)', fontsize=14)
plt.ylabel('振幅', fontsize=14)
plt.show()
このコードでは、fontsizeでフォントサイズを、fontweightでフォントの太さを指定しています。
以下、実行結果です。

凡例の設定
複数のデータセットを一つのグラフに表示する場合、凡例は非常に重要です。
import matplotlib.pyplot as plt import japanize_matplotlib import numpy as np x = np.linspace(0, 10, 100) y1 = np.sin(x) y2 = np.cos(x) plt.figure(figsize=(10, 6)) plt.plot(x, y1, label='sin(x)') plt.plot(x, y2, label='cos(x)') plt.legend(loc='lower left', fontsize=12, frameon=True, facecolor='white', edgecolor='black') plt.show()
locで凡例の位置を、frameonで枠の表示を、facecolorとedgecolorで背景色と枠の色を指定しています。
以下、実行結果です。

色とスタイルの変更
線の色やスタイルを変更することで、データをより見やすく、また美しく表現できます。
import matplotlib.pyplot as plt import japanize_matplotlib import numpy as np x = np.linspace(0, 10, 100) y1 = np.sin(x) y2 = np.cos(x) plt.figure(figsize=(10, 6)) plt.plot(x, y1, color='red', linestyle='--', linewidth=2, marker='o', markersize=5, label='sin(x)') plt.plot(x, y2, color='blue', linestyle='-', linewidth=2, marker='s', markersize=5, label='cos(x)') plt.legend() plt.grid(True, linestyle=':', alpha=0.7) plt.show()
このコードでは、colorで線の色を、linestyleで線のスタイルを、linewidthで線の太さを、markerでマーカーの形を、markersizeでマーカーのサイズを指定しています。
また、plt.grid()でグリッド線のスタイルも設定しています。
以下、実行結果です。

軸の範囲とスケールの調整
データの特性に応じて、軸の範囲やスケールを調整することが重要です。
import matplotlib.pyplot as plt
import japanize_matplotlib
import numpy as np
x = np.linspace(0, 10, 100)
y = np.exp(x)
plt.figure(figsize=(10, 6))
plt.plot(x, y)
plt.xlim(0, 5)
plt.ylim(1, 1000)
plt.yscale('log')
plt.xlabel('x')
plt.ylabel('exp(x)')
plt.title('指数関数のグラフ')
plt.show()
plt.xlim()とplt.ylim()で軸の範囲を、plt.yscale('log')でy軸を対数スケールに設定しています。
以下、実行結果です。

複数のサブプロット
基本的なサブプロットの作成
まず、最も基本的な方法として、plt.subplot()を使用して複数のグラフを配置する方法を見ていきます。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
plt.figure(figsize=(12, 8))
# 1行目、1列目のサブプロット
plt.subplot(2, 2, 1)
plt.plot(x, np.sin(x))
plt.title('sin(x)')
# 1行目、2列目のサブプロット
plt.subplot(2, 2, 2)
plt.plot(x, np.cos(x))
plt.title('cos(x)')
# 2行目、1列目のサブプロット
plt.subplot(2, 2, 3)
plt.plot(x, np.exp(x))
plt.title('exp(x)')
# 2行目、2列目のサブプロット
plt.subplot(2, 2, 4)
plt.plot(x, np.log(1+x))
plt.title('log(1+x)')
plt.tight_layout()
plt.show()
このコードでは、plt.subplot(2, 2, n)を使用して2×2のグリッドにサブプロットを配置しています。
最初の2つの引数はグリッドのサイズ、3つ目の引数はサブプロットの位置を指定します。
plt.tight_layout()は、サブプロット間の間隔を自動調整します。
以下、実行結果です。

グリッドレイアウトの活用
より柔軟なレイアウトを実現するために、plt.GridSpecを使用することができます。
これにより、異なるサイズのサブプロットを配置することが可能になります。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig = plt.figure(figsize=(12, 8))
gs = fig.add_gridspec(3, 3)
# 2行x2列のサブプロット
ax1 = fig.add_subplot(gs[0:2, 0:2])
ax1.plot(x, np.sin(x))
ax1.set_title('sin(x)')
# 1行x1列のサブプロット(右上)
ax2 = fig.add_subplot(gs[0, 2])
ax2.plot(x, np.cos(x))
ax2.set_title('cos(x)')
# 1行x1列のサブプロット(右中)
ax3 = fig.add_subplot(gs[1, 2])
ax3.plot(x, np.exp(x))
ax3.set_title('exp(x)')
# 1行x3列のサブプロット(下)
ax4 = fig.add_subplot(gs[2, :])
ax4.plot(x, np.log(1+x))
ax4.set_title('log(1+x)')
plt.tight_layout()
plt.show()
このコードでは、GridSpecを使用して3×3のグリッドを作成し、それを基にして異なるサイズのサブプロットを配置しています。
gs[0:2, 0:2]のように、スライスを使用してグリッドのセルを指定することで、複数のセルにまたがるサブプロットを作成できます。
以下、実行結果です。

共有軸の設定
複数のサブプロットで軸を共有することで、データの比較がより容易になります。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8), sharex=True)
ax1.plot(x, np.sin(x))
ax1.set_title('sin(x)')
ax2.plot(x, np.cos(x))
ax2.set_title('cos(x)')
ax2.set_xlabel('x')
fig.text(0, 0.5, 'Amplitude', va='center', rotation='vertical')
plt.tight_layout()
plt.show()
このコードでは、plt.subplots()のsharex=Trueパラメータを使用して、x軸を共有しています。
また、fig.text()を使用して、共通のy軸ラベルを追加しています。
以下、実行結果です。

特殊なグラフタイプ
ヒストグラム
ヒストグラムは、データの分布を視覚化するのに適しています。データを区間(ビン)に分け、各区間に含まれるデータの頻度を表示します。
以下、コードです。
import matplotlib.pyplot as plt
import japanize_matplotlib
import numpy as np
# データの生成
data = np.random.randn(1000)
plt.figure(figsize=(10, 6))
plt.hist(data, bins=30, edgecolor='black')
plt.title('ヒストグラム')
plt.xlabel('値')
plt.ylabel('頻度')
plt.show()
このコードでは、plt.hist()関数を使用してヒストグラムを作成しています。binsパラメータでビンの数を指定し、edgecolorで各バーの境界線の色を設定しています。
以下、実行結果です。

箱ひげ図
箱ひげ図(ボックスプロット)は、データの分布を要約的に表現するのに適しています。中央値、四分位数、外れ値などの情報を一度に表示できます。
以下、コードです。
import matplotlib.pyplot as plt
import japanize_matplotlib
import numpy as np
# データの生成
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
plt.figure(figsize=(10, 6))
plt.boxplot(data, labels=['Group 1', 'Group 2', 'Group 3'])
plt.title('箱ひげ図')
plt.ylabel('値')
plt.show()
このコードでは、plt.boxplot()関数を使用して箱ひげ図を作成しています。
3つの異なる標準偏差を持つ正規分布からデータを生成し、それぞれをグループとして表示しています。
以下、実行結果です。

円グラフ
円グラフは、全体に対する各部分の割合を視覚化するのに適しています。ただし、多すぎるカテゴリがある場合は見づらくなるため、使用には注意が必要です。
以下、コードです。
import matplotlib.pyplot as plt
import japanize_matplotlib
import numpy as np
# データの準備
sizes = [35, 30, 20, 15]
labels = ['A', 'B', 'C', 'D']
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
explode = (0, 0.1, 0, 0) # 2番目の要素を強調
plt.figure(figsize=(10, 8))
plt.pie(sizes, explode=explode, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
plt.axis('equal') # 円を真円にする
plt.title('円グラフ')
plt.show()
このコードでは、plt.pie()関数を使用して円グラフを作成しています。
explodeパラメータで特定の要素を強調表示し、autopctパラメータでパーセンテージを表示しています。
以下、実行結果です。

まとめ
今回は、matplotlibを使用したPythonでのデータ可視化の基礎のお話しをしました。
matplotlibの基本的な使い方から始まり、様々な種類のグラフの作成方法、グラフのカスタマイズ技術、複数のサブプロットの作成まで幅広く カバー しました。
これらの知識を活用することで、データの傾向や特徴を効果的に可視化できるようになります。
次のステップとしては、より高度なmatplotlibの機能の探求や、他の可視化ライブラリの学習がおすすめです。
また、実際のプロジェクトでこれらの技術を適用し、経験を積むことが重要です。データ可視化は継続的な学習と実践が鍵となります。

