Pythonデータ可視化の第一歩 – matplotlib 入門

Pythonデータ可視化の第一歩 – matplotlib 入門

データは私たちの周りに溢れていますが、その意味を理解するには可視化が欠かせません。

Pythonの強力なライブラリ、matplotlibを使えば、複雑なデータでも美しく分かりやすいグラフに変換できます。

今回は、matplotlibの基礎からステップバイステップで解説します。

誰もがデータの物語を視覚的に語れるようになるでしょう。

はじめに

 データ可視化の重要性

私たちは日々、膨大な量のデータに囲まれています。ビジネス、科学研究、社会現象など、あらゆる分野でデータが生成され、蓄積されています。

しかし、生のデータだけでは、その中に隠れている重要な洞察や傾向を見出すのは困難です。ここで力を発揮するのが、データ可視化です。

データ可視化は、複雑なデータセットを視覚的に表現することで、以下のような利点をもたらします。

  • 傾向や異常値の素早い発見
  • 複雑な概念やアイデアの効果的な伝達
  • データ間の関係性の理解促進
  • 意思決定プロセスの支援

 

適切に設計されたグラフや図表は、数千行のデータを一目で理解可能にし、重要な情報を即座に伝えることができます。

 

 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.pyplotpltとしてインポートします。pltは慣例的なもので、別名として利用できます。
  • japanize_matplotlibは、グラフ内で日本語を利用するときに必要になります。
  • numpynpとしてインポートします。数値計算に使用します。
  • 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オブジェクト(ax1ax2)に対してプロットやカスタマイズを行います。
  • 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で枠の表示を、facecoloredgecolorで背景色と枠の色を指定しています。

 

以下、実行結果です。

 

 色とスタイルの変更

線の色やスタイルを変更することで、データをより見やすく、また美しく表現できます。

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の機能の探求や、他の可視化ライブラリの学習がおすすめです。

また、実際のプロジェクトでこれらの技術を適用し、経験を積むことが重要です。データ可視化は継続的な学習と実践が鍵となります。