データは私たちの周りに溢れていますが、その意味を理解するには可視化が欠かせません。
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の機能の探求や、他の可視化ライブラリの学習がおすすめです。
また、実際のプロジェクトでこれらの技術を適用し、経験を積むことが重要です。データ可視化は継続的な学習と実践が鍵となります。