すぐに使える!Matplotlibで始めるデータ可視化 – 基礎から応用まで徹底解説
はじめに
データは現代社会において非常に重要な資産です。ビジネス、科学、医療、エンターテイメントなど、あらゆる分野でデータが収集され、活用されています。しかし、生データのままではその中に隠されたパターン、傾向、インサイトを理解することは困難です。ここで「データ可視化」の出番となります。
データ可視化は、データをグラフや図などの視覚的な形式に変換することで、データの持つ情報を直感的に理解しやすくする手法です。複雑なデータセットからでも、一目でトレンドや異常値を把握できるようになります。データ可視化は、データ分析の過程でデータの探索、仮説の検証、そして分析結果の共有において不可欠なツールです。
データ可視化のためのツールは数多く存在しますが、Pythonプログラマーにとって最も広く使われているライブラリの一つが Matplotlib です。Matplotlibは、Pythonで静的な、アニメーション付きの、インタラクティブな可視化を作成するための包括的なライブラリです。シンプルかつ強力で、非常に高いカスタマイズ性を持っているため、初心者から上級者まで幅広く利用されています。
この記事では、Matplotlibを使ってデータ可視化を始めるために必要な基礎知識から、様々なグラフの作成方法、さらにはカスタマイズや応用的なテクニックまで、詳細かつ実践的に解説します。この記事を読めば、あなたもMatplotlibを使いこなし、データを魅力的なグラフに変換できるようになるでしょう。
さあ、Matplotlibの世界へ飛び込みましょう!
第1章: Matplotlibを始める準備
Matplotlibを使うためには、まずPython環境が整っている必要があります。まだPythonを使ったことがない、あるいは環境構築に自信がないという方もご安心ください。ここでは、推奨されるPython環境とMatplotlibのインストール方法を解説します。
1.1 Python環境のセットアップ
データ分析や可視化を行う際には、Python本体だけでなく、関連するライブラリ(NumPy, Pandasなど)もまとめて管理できる環境が望ましいです。そこで推奨されるのが、Anaconda または Miniconda です。
- Anaconda: データサイエンスに必要な主要なライブラリ(Python本体、NumPy, Pandas, Matplotlib, Jupyter Notebookなど)があらかじめ含まれているディストリビューションです。インストールするだけで必要なものがほとんど揃います。初心者の方には最も手軽でおすすめです。
- Miniconda: Anacondaの軽量版で、Python本体とパッケージ管理システムであるcondaだけが含まれています。必要なライブラリを後から自分でインストールしていく形式です。ディスク容量を節約したい場合や、必要なライブラリを自分で選びたい場合に適しています。
どちらか一方をインストールしてください。公式ウェブサイトからインストーラーをダウンロードし、指示に従ってインストールを進めます。インストール後、ターミナル(またはコマンドプロンプト)を開き、python --version
と入力してPythonのバージョンが表示されれば成功です。
conda環境の代わりに、Python標準の仮想環境(venv)とpipを使う方法でも問題ありません。ただし、依存関係の管理という点ではcondaの方が優れている場合があります。
1.2 Matplotlibのインストール
AnacondaまたはMinicondaをインストールした場合、多くの場合Matplotlibはすでに含まれています。念のため、以下のコマンドで確認またはインストールできます。
ターミナル(またはコマンドプロンプト)を開き、以下のコマンドを実行します。
“`bash
Anaconda/Minicondaの場合
conda install matplotlib numpy pandas jupyterlab
venv + pip の場合
pip install matplotlib numpy pandas jupyterlab
“`
これらのコマンドは、Matplotlibだけでなく、後ほどデータ操作やJupyter環境で使用するNumPy, Pandas, JupyterLabも一緒にインストールします。conda install
または pip install
の後にライブラリ名を指定することで、複数のライブラリを一度にインストールできます。
インストールが完了したら、Pythonの対話環境(またはJupyter環境)でMatplotlibがインポートできるか確認しましょう。
python
import matplotlib
print(matplotlib.__version__)
バージョン番号が表示されれば、インストールは成功です。
1.3 Jupyter Notebook/Labの使用推奨
データ可視化のコードを記述し、その場でグラフを確認しながら作業するには、Jupyter Notebook または JupyterLab の使用を強く推奨します。
- Jupyter Notebook: ウェブブラウザ上で動作する対話型の開発環境です。コード、実行結果、説明文などを一つのドキュメントにまとめて管理できます。コードを実行するたびにグラフがその場に表示されるため、試行錯誤しながら可視化を進めるのに非常に適しています。
- JupyterLab: Jupyter Notebookの後継であり、さらに多機能な統合開発環境です。ファイルブラウザ、ターミナル、エディタなど、Notebook以外の機能も統合されています。
Anaconda/Minicondaをインストールしていれば、JupyterLabもインストールされているはずです。ターミナルで jupyter lab
と入力すれば起動できます。
Jupyter環境でMatplotlibを使う場合、グラフをインライン表示させるためのおまじないが必要です。Notebookの最初のセルに以下のマジックコマンドを記述して実行してください。
python
%matplotlib inline
これにより、plt.show()
を明示的に呼び出さなくても、セルを実行するだけでグラフが表示されるようになります。(JupyterLabのバージョンによってはこのマジックコマンドなしでも表示されることがありますが、書いておくと安心です。)
1.4 基本的なインポート
Matplotlibを使ってグラフを作成する際には、通常 matplotlib.pyplot
モジュールを使用します。慣例として、これを plt
というエイリアスでインポートします。また、データを生成したり操作したりするためにNumPyを使うことも多いので、これも np
というエイリアスでインポートしておきましょう。
python
import matplotlib.pyplot as plt
import numpy as np
この2行は、Matplotlibを使ったスクリプトやNotebookの冒頭で頻繁に登場します。
これで、Matplotlibを使ってデータ可視化を始める準備が整いました。次の章では、Matplotlibの基本的な概念について掘り下げます。
第2章: Matplotlibの基本概念
Matplotlibでグラフを作成する際には、いくつかの重要な概念を理解しておく必要があります。特に、「Figure」と「Axes」の関係性、そしてグラフを作成するための二つの主要なAPI(Pyplot APIとオブジェクト指向API)について知っておくと、より柔軟で高度な可視化が可能になります。
2.1 FigureとAxesの関係性
Matplotlibのグラフ構造は、美術作品に例えると理解しやすいかもしれません。
- Figure (図全体): キャンバス全体や、グラフが描かれるウィンドウ全体を指します。これには、一つまたは複数のグラフ(Axes)が含まれます。タイトル、全体のサイズ、解像度などもFigureの属性として設定できます。
- Axes (軸付き描画領域): Figure上に配置される個々のグラフ描画領域です。これには、x軸、y軸、タイトル、ラベル、プロットされたデータなどが含まれます。Axesは、グラフの「中身」を構成する最も基本的な要素と言えます。Axesという名前ですが、必ずしも軸があるとは限りません(例えば円グラフ)。重要なのは、これが「データがプロットされる領域」であるという点です。
一つのFigure内に複数のAxesを配置することで、複数のグラフを並べて表示したり、挿入図を作成したりできます。
2.2 Pyplot APIとオブジェクト指向API
Matplotlibには、グラフを作成するための主なインターフェースが二つあります。
-
Pyplot API (ステートベース):
matplotlib.pyplot
モジュールを通じて提供されるAPIです。簡単なグラフを素早く作成するのに適しています。関数を呼び出すだけで、内部でFigureやAxesが自動的に作成・管理されます。例えば、plt.plot()
を呼び出すと、現在のFigureの現在のAxesに折れ線グラフが描画されます。もしFigureやAxesが存在しなければ、自動的に新しいものが作成されます。インタラクティブな環境やスクリプトで手軽にグラフを作成する場合によく使われます。“`python
Pyplot API の例
plt.plot([1, 2, 3, 4], [10, 20, 25, 30])
plt.xlabel(‘X軸’)
plt.ylabel(‘Y軸’)
plt.title(‘Pyplot API を使ったグラフ’)
plt.show() # Jupyter環境では不要な場合が多い
“` -
オブジェクト指向API: FigureやAxesのオブジェクトを明示的に作成し、それらのオブジェクトのメソッドを呼び出してグラフを作成・カスタマイズするAPIです。より複雑なグラフを作成したり、複数のグラフを細かく制御したりする場合に適しています。Matplotlibの内部構造を反映しており、より柔軟で強力な可視化が可能です。特に、複数のAxesを持つFigureを作成する場合には、オブジェクト指向APIを使うのが一般的です。
“`python
オブジェクト指向 API の例
fig, ax = plt.subplots() # Figure と Axes を同時に作成
ax.plot([1, 2, 3, 4], [10, 20, 25, 30])
ax.set_xlabel(‘X軸’)
ax.set_ylabel(‘Y軸’)
ax.set_title(‘オブジェクト指向 API を使ったグラフ’)fig.show() は通常使わない
plt.show() # 最終的に表示するために plt.show() を呼ぶこともありますが、
# オブジェクト指向API自体は fig や ax のメソッドで操作します。
# Jupyter環境では最後のセル実行結果として fig が自動的に表示されることが多い
“`
どちらのAPIを使うべきかという明確なルールはありませんが、一般的には以下の使い分けが推奨されます。
- 簡単な単一グラフ: Pyplot API (
plt.plot
,plt.scatter
など) で手軽に作成。 - 複数のグラフ、複雑なカスタマイズ: オブジェクト指向 API (
fig, ax = plt.subplots()
,ax.plot
,ax.set_xlabel
など) で制御性を高める。
この記事では、両方のAPIのコード例を示し、それぞれの使い方を解説していきます。特に、複数のグラフを扱う後半の章ではオブジェクト指向APIを中心に解説します。
2.3 基本的なプロット関数
グラフを描画するための最も基本的な関数は plt.plot()
(Pyplot API) または ax.plot()
(オブジェクト指向API) です。これは主に折れ線グラフを描画するために使用されますが、マーカーだけを表示させれば散布図のような使い方もできます。
基本的な使い方は、x座標のデータのリスト(またはNumPy配列)とy座標のデータのリスト(またはNumPy配列)を引数として渡すだけです。
“`python
import matplotlib.pyplot as plt
import numpy as np
Pyplot API
plt.plot([1, 2, 3, 4], [5, 8, 6, 9])
plt.show() # Jupyterでは不要
オブジェクト指向 API
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [5, 8, 6, 9])
plt.show() # Jupyterでは不要
“`
引数を一つだけ渡した場合、それはy座標のデータと見なされ、x座標は自動的に0から始まるインデックス(0, 1, 2, …)になります。
“`python
y座標だけ指定した場合
plt.plot([10, 12, 8, 15]) # x座標は自動的に [0, 1, 2, 3] となる
plt.show()
“`
2.4 データの準備(NumPy配列の利用)
実際のデータ可視化では、NumPy配列やPandas DataFrameに格納されたデータを使うことがほとんどです。Matplotlibはこれらのデータ構造を直接扱えるため非常に便利です。特にNumPyは数値計算に強く、データの生成や加工によく使われます。
例として、NumPyを使ってサインカーブのデータを生成し、プロットしてみましょう。
“`python
import matplotlib.pyplot as plt
import numpy as np
0から2πまでの範囲を100分割したデータを作成
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
プロット
plt.plot(x, y)
plt.title(‘サインカーブ’)
plt.xlabel(‘x’)
plt.ylabel(‘sin(x)’)
plt.show()
“`
np.linspace(start, stop, num)
は、指定された範囲 start
から stop
までを num
個の等間隔な要素を持つNumPy配列を生成する関数です。このようにNumPyを使うことで、簡単にプロット用のデータを準備できます。
これで、Matplotlibの基本的な構造とデータ準備の方法が理解できました。次の章では、様々な基本的なグラフタイプを作成する方法を具体的なコード例と共に見ていきます。
第3章: 基本的なグラフの作成
この章では、データ可視化で最も頻繁に利用される基本的なグラフタイプ、すなわち折れ線グラフ、散布図、棒グラフ、ヒストグラム、円グラフの作成方法を学びます。それぞれのグラフがどのような目的で使われるか、そしてMatplotlibでどのように作成するかをコード例を交えて解説します。
これらの基本的なグラフ作成には、Pyplot API (plt.plot
, plt.scatter
など) が手軽で便利です。オブジェクト指向API (ax.plot
, ax.scatter
など) を使う場合も、基本的には対応するPyplot関数の前に ax.
を付けるだけなので、適宜読み替えてください。
3.1 折れ線グラフ (Line Plot)
折れ線グラフは、連続的なデータの変化や時系列データのトレンドを示すのに適しています。時間の経過に伴う株価の変動、気温の変化、人口の推移などを可視化する際によく使用されます。
基本的な作成方法は、前述の plt.plot(x, y)
または ax.plot(x, y)
です。
“`python
import matplotlib.pyplot as plt
import numpy as np
月ごとの売上データ (例)
months = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
sales = np.array([150, 180, 220, 200, 250, 280, 300, 290, 260, 230, 200, 180])
plt.plot(months, sales)
plt.title(‘月ごとの売上’)
plt.xlabel(‘月’)
plt.ylabel(‘売上 (万円)’)
plt.xticks(months) # x軸の目盛りを月の数値にする
plt.grid(True) # グリッドを表示
plt.show()
“`
単一の折れ線
上の例は単一の折れ線グラフです。plt.plot()
に渡すxとyのデータは、同じ長さである必要があります。
複数の折れ線
一つのグラフに複数の折れ線を表示するには、plt.plot()
を複数回呼び出すだけです。Matplotlibは自動的に異なる色を使ってくれます。
“`python
異なる商品の月ごとの売上 (例)
sales_product_a = np.array([150, 180, 220, 200, 250, 280, 300, 290, 260, 230, 200, 180])
sales_product_b = np.array([100, 120, 150, 180, 200, 220, 250, 240, 210, 180, 150, 130])
months = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
plt.plot(months, sales_product_a, label=’商品A’) # labelで凡例に表示する名前を指定
plt.plot(months, sales_product_b, label=’商品B’)
plt.title(‘商品別 月ごとの売上’)
plt.xlabel(‘月’)
plt.ylabel(‘売上 (万円)’)
plt.xticks(months)
plt.grid(True)
plt.legend() # 凡例を表示
plt.show()
“`
線種、色、マーカーの指定
plt.plot()
関数には、線のスタイルを制御するための様々な引数があります。
color
(またはc
): 線の色を指定します。色の名前(’red’, ‘blue’, ‘green’など)、16進数コード(’#FF5733’など)、RGBタプルなどを指定できます。linestyle
(またはls
): 線の種類を指定します。’-‘ (実線), ‘–‘ (破線), ‘-.’ (一点鎖線), ‘:’ (点線) などがあります。linewidth
(またはlw
): 線の太さを指定します。数値で指定します。marker
: 各データポイントに表示するマーカーの形状を指定します。’o’ (円), ‘x’ (バツ), ‘*’ (星), ‘.’ (点) など様々な種類があります。markersize
(またはms
): マーカーのサイズを指定します。label
: その折れ線に付けるラベル名を指定します。plt.legend()
と組み合わせて凡例を表示する際に使います。
これらをまとめて文字列で指定するショートカットもよく使われます。例えば、'bo--'
は「青色 (b) の円形マーカー (o) を持つ破線 (– )」という意味になります。
“`python
x = np.linspace(0, 10, 50)
y1 = np.sin(x)
y2 = np.cos(x)
plt.plot(x, y1, color=’red’, linestyle=’–‘, label=’sin(x)’)
plt.plot(x, y2, ‘bo-‘, label=’cos(x)’) # ショートカット記法
plt.title(‘サインとコサイン’)
plt.xlabel(‘x’)
plt.ylabel(‘y’)
plt.legend()
plt.show()
“`
ラベル、タイトル、凡例の追加
グラフに情報を加えることは、そのグラフを理解しやすくするために非常に重要です。
plt.title('タイトル')
: グラフ全体のタイトルを設定します。plt.xlabel('X軸ラベル')
: X軸のラベルを設定します。plt.ylabel('Y軸ラベル')
: Y軸のラベルを設定します。plt.legend()
:plt.plot()
関数などでlabel
引数で指定した凡例を表示します。
これらの関数は、現在のAxesに対して設定を行います。オブジェクト指向APIの場合は、対応する ax.set_title()
, ax.set_xlabel()
, ax.set_ylabel()
, ax.legend()
メソッドを使用します。
軸の範囲の設定
グラフに表示する軸の範囲を明示的に設定することもできます。
plt.xlim(xmin, xmax)
: X軸の表示範囲をxmin
からxmax
までに設定します。plt.ylim(ymin, ymax)
: Y軸の表示範囲をymin
からymax
までに設定します。
“`python
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title(‘サインカーブ (限定範囲)’)
plt.xlabel(‘x’)
plt.ylabel(‘sin(x)’)
plt.xlim(np.pi/2, 3*np.pi/2) # X軸をπ/2から3π/2までにする
plt.ylim(-0.8, 0.8) # Y軸を-0.8から0.8までにする
plt.show()
“`
3.2 散布図 (Scatter Plot)
散布図は、二つの数値変数間の関係性(相関)を示すのに適しています。各データポイントは、x軸の値とy軸の値によって二次元平面上の点としてプロットされます。例えば、身長と体重の関係、広告費と売上の関係などを可視化する際に使用されます。
基本的な作成方法は plt.scatter(x, y)
です。
“`python
import matplotlib.pyplot as plt
import numpy as np
ランダムなデータを作成
np.random.seed(0) # 乱数のシードを固定
x = np.random.rand(50) * 100 # 0から100までの乱数50個
y = np.random.rand(50) * 100 # 0から100までの乱数50個
plt.scatter(x, y)
plt.title(‘ランダムな散布図’)
plt.xlabel(‘X値’)
plt.ylabel(‘Y値’)
plt.show()
“`
点のサイズ、色、透明度の指定
散布図の点の見た目をカスタマイズすることで、より多くの情報をエンコードできます。
s
: マーカーのサイズを指定します。数値または数値のリスト/配列を指定できます。リスト/配列の場合、データポイントごとに異なるサイズになります。c
: マーカーの色を指定します。色の名前、16進数コード、RGBタプルなどを指定できます。数値のリスト/配列を指定した場合、カラーマップを使ってデータポイントごとに異なる色を割り当てられます。alpha
: マーカーの透明度を指定します。0.0 (完全に透明) から 1.0 (完全に不透明) までの値を指定します。データポイントが重なっている領域を強調したい場合に便利です。
“`python
サイズと色に意味を持たせた散布図の例
np.random.seed(0)
x = np.random.rand(50) * 100
y = np.random.rand(50) * 100
sizes = np.random.rand(50) * 500 # サイズを表すデータ
colors = np.random.rand(50) # 色を表すデータ (カラーマップでマッピングされる)
plt.scatter(x, y, s=sizes, c=colors, alpha=0.7, cmap=’viridis’)
plt.title(‘サイズと色で情報をエンコードした散布図’)
plt.xlabel(‘X値’)
plt.ylabel(‘Y値’)
plt.colorbar(label=’色の意味’) # カラーバーを追加
plt.show()
“`
cmap='viridis'
は使用するカラーマップを指定しています。Matplotlibには様々なカラーマップが用意されています(詳細は後述)。plt.colorbar()
は、色の濃淡が何を表しているかを示すためのカラーバーを追加します。
3.3 棒グラフ (Bar Chart)
棒グラフは、カテゴリ別の数量や頻度を比較するのに適しています。各カテゴリは棒で表され、棒の長さがそのカテゴリの値を表します。商品の売上、アンケートの回答数、クラス別の人数などを可視化する際に使用されます。
縦棒グラフ (plt.bar
)
カテゴリがX軸に並び、値がY軸で表現される棒グラフです。
“`python
import matplotlib.pyplot as plt
import numpy as np
カテゴリデータ
categories = [‘A’, ‘B’, ‘C’, ‘D’, ‘E’]
values = [25, 40, 30, 35, 20]
棒グラフの作成
plt.bar(categories, values)
plt.title(‘カテゴリ別の値’)
plt.xlabel(‘カテゴリ’)
plt.ylabel(‘値’)
plt.show()
“`
plt.bar()
の最初の引数はカテゴリのラベル(X軸の位置)、二つ目の引数は各カテゴリに対応する値(棒の高さ)です。
横棒グラフ (plt.barh
)
カテゴリがY軸に並び、値がX軸で表現される棒グラフです。長いカテゴリ名を持つ場合などに可視化しやすいことがあります。
“`python
横棒グラフの作成
plt.barh(categories, values) # 引数の順番は bar と同じ
plt.title(‘カテゴリ別の値 (横棒)’)
plt.xlabel(‘値’)
plt.ylabel(‘カテゴリ’)
plt.show()
“`
複数の系列を持つ棒グラフ(並列、積み上げ)
複数の系列を持つデータを棒グラフで表現する場合、棒を並べて表示するか、積み上げて表示するかの選択肢があります。
並列棒グラフ: 異なる系列の棒をカテゴリごとに隣り合わせて表示します。
“`python
複数系列のデータ (例: 2年間のカテゴリ別売上)
categories = [‘A’, ‘B’, ‘C’, ‘D’, ‘E’]
values_2022 = np.array([25, 40, 30, 35, 20])
values_2023 = np.array([30, 45, 35, 40, 25])
x = np.arange(len(categories)) # カテゴリ数に応じたX軸の位置を生成
width = 0.35 # 棒の幅
plt.bar(x – width/2, values_2022, width, label=’2022年’)
plt.bar(x + width/2, values_2023, width, label=’2023年’)
plt.title(‘カテゴリ別 売上 (2年間比較)’)
plt.xlabel(‘カテゴリ’)
plt.ylabel(‘売上 (万円)’)
plt.xticks(x, categories) # X軸の目盛りをカテゴリ名にする
plt.legend()
plt.show()
“`
np.arange(len(categories))
で棒を配置する基準となるX座標を生成し、棒の幅の半分だけ左右にずらすことで棒を並べています。plt.xticks(x, categories)
で、生成したX座標の位置にカテゴリ名をラベルとして設定しています。
積み上げ棒グラフ: 異なる系列の棒をカテゴリごとに積み重ねて表示します。合計値の比較と、その内訳の比較に適しています。
“`python
積み上げ棒グラフ
plt.bar(categories, values_2022, label=’2022年’)
bottom= に前の系列の値を渡すことで積み上げになる
plt.bar(categories, values_2023, bottom=values_2022, label=’2023年’)
plt.title(‘カテゴリ別 売上 (積み上げ)’)
plt.xlabel(‘カテゴリ’)
plt.ylabel(‘売上 (万円)’)
plt.legend()
plt.show()
“`
plt.bar()
を重ねて呼び出し、2つ目以降の呼び出しで bottom
引数に前の棒の高さ(またはそれまでの合計の高さ)を指定することで積み上げ棒グラフを作成できます。
色の指定、エッジカラー、幅
plt.bar()
や plt.barh()
も color
, edgecolor
(棒の枠線の色), width
(縦棒の場合の幅), height
(横棒の場合の高さ) などの引数で見た目をカスタマイズできます。
python
plt.bar(categories, values, color='skyblue', edgecolor='navy', width=0.7)
plt.title('カスタマイズされた棒グラフ')
plt.xlabel('カテゴリ')
plt.ylabel('値')
plt.show()
3.4 ヒストグラム (Histogram)
ヒストグラムは、数値データの分布の形状を要約するのに適しています。データをいくつかの区間(ビン)に分け、各ビンに含まれるデータの数を棒の高さで表します。例えば、試験の得点分布、身長の分布、ある期間のトラフィック量などを可視化する際に使用されます。
基本的な作成方法は plt.hist(data, bins=...)
です。
“`python
import matplotlib.pyplot as plt
import numpy as np
ランダムな正規分布データを作成
np.random.seed(0)
data = np.random.randn(1000) # 平均0、標準偏差1の正規分布に従う1000個のデータ
ヒストグラムの作成
plt.hist(data, bins=30) # データを30個のビンに分割
plt.title(‘正規分布データのヒストグラム’)
plt.xlabel(‘値’)
plt.ylabel(‘度数’)
plt.show()
“`
bins
引数には、ビンの数を指定するのが一般的ですが、ビンの境界値をリストやNumPy配列で直接指定することも可能です。
正規化 (density
)
density=True
を指定すると、各ビンの高さが度数ではなく、面積の合計が1になるように正規化された確率密度になります。これにより、異なるサイズのデータセットの分布を比較しやすくなります。
“`python
正規化されたヒストグラム
plt.hist(data, bins=30, density=True, alpha=0.7, color=’green’) # αで透明度を指定
正規分布の確率密度関数を重ね書きしてみる
mu, std = 0, 1 # 平均と標準偏差
x = np.linspace(-4, 4, 100)
pdf = 1/(std * np.sqrt(2np.pi)) * np.exp(-(x-mu)2 / (2std**2))
plt.plot(x, pdf, color=’red’, linestyle=’–‘, label=’正規分布PDF’)
plt.title(‘正規化されたヒストグラム’)
plt.xlabel(‘値’)
plt.ylabel(‘確率密度’)
plt.legend()
plt.show()
“`
3.5 円グラフ (Pie Chart)
円グラフは、全体に対する各カテゴリの割合を示すのに適しています。円全体が100%を表し、各カテゴリは扇形(スライス)で表現されます。予算の内訳、市場シェア、アンケートの選択肢の割合などを可視化する際によく使用されます。ただし、カテゴリ数が多かったり、各カテゴリの割合が非常に近かったりする場合は、比較が難しくなるため、棒グラフなど他のグラフタイプの方が適していることもあります。
基本的な作成方法は plt.pie(values, labels=...)
です。
“`python
import matplotlib.pyplot as plt
import numpy as np
支出の内訳 (例)
expenses = np.array([300, 400, 200, 100])
categories = [‘食費’, ‘家賃’, ‘交通費’, ‘その他’]
円グラフの作成
plt.pie(expenses, labels=categories, autopct=’%1.1f%%’) # autopct で割合を表示
plt.title(‘月間支出の内訳’)
plt.axis(‘equal’) # 円を真円にする (‘equal’ または ‘tight’)
plt.show()
“`
values
: 各スライスの大きさを表す数値のリスト/配列です。これらの合計が円全体の大きさとなります。labels
: 各スライスに対応するラベルのリスト/配列です。autopct
: 各スライスに割合をテキストとして表示するためのフォーマット文字列です。例えば'%1.1f%%'
は「小数点以下1桁までの浮動小数点数に%を付ける」という意味になります。plt.axis('equal')
: アスペクト比を等しくすることで、円を楕円ではなく真円として描画します。
特定のスライスの強調 (explode
)
特定のスライスを円の中心から少し離して表示することで、そのスライスを強調できます。
“`python
家賃のスライスを強調
explode = [0, 0.1, 0, 0] # 各スライスに対して、円の中心からの距離を指定 (0は離さない)
plt.pie(expenses, labels=categories, autopct=’%1.1f%%’, explode=explode, shadow=True, startangle=90)
plt.title(‘月間支出の内訳 (家賃を強調)’)
plt.axis(‘equal’)
plt.show()
“`
explode
: 各スライスをどれだけ中心から離すかを数値のリスト/配列で指定します。shadow
: スライスに影を付けるかどうかをTrue
/False
で指定します。startangle
: 最初のスライスが始まる角度を指定します(デフォルトは0度でX軸正の方向、反時計回り)。
第4章: グラフのカスタマイズ
Matplotlibの最大の強みの一つは、その高いカスタマイズ性です。グラフのほぼ全ての要素(タイトル、ラベル、軸、色、フォント、スタイルなど)を細かく制御できます。この章では、グラフの見栄えを向上させ、より分かりやすくするための様々なカスタマイズ方法を学びます。
以降は、オブジェクト指向API (fig, ax = plt.subplots()
) を中心に解説します。Pyplot APIを使いたい場合は、対応する plt.
関数に読み替えてください(例: ax.set_title
は plt.title
、ax.set_xlabel
は plt.xlabel
など)。
“`python
import matplotlib.pyplot as plt
import numpy as np
例として使うデータ
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
FigureとAxesの作成
fig, ax = plt.subplots(figsize=(8, 5)) # Figureサイズを指定
ax.plot(x, y1, label=’sin(x)’)
ax.plot(x, y2, label=’cos(x)’)
ここからカスタマイズの例
“`
4.1 タイトル、ラベル、凡例
オブジェクト指向APIでは、ax
オブジェクトのメソッドを使ってタイトルやラベルを設定します。
“`python
ax.set_title(‘カスタマイズされたサイン・コサイン曲線’, fontsize=16, color=’darkproxy’)
ax.set_xlabel(‘X軸’, fontsize=12, color=’gray’)
ax.set_ylabel(‘Y軸’, fontsize=12, color=’gray’)
ax.legend(loc=’upper right’, fontsize=10) # 凡例の位置とフォントサイズを指定
fig # Jupyter環境では fig を最後に書くと表示される
または plt.show()
“`
set_title
,set_xlabel
,set_ylabel
: タイトルとラベルを設定します。fontsize
,color
などの引数でスタイルを調整できます。legend()
: 凡例を表示します。loc
引数で位置を指定できます(’upper right’, ‘upper left’, ‘lower left’, ‘lower right’, ‘right’, ‘center left’, ‘center right’, ‘lower center’, ‘upper center’, ‘center’, または座標のタプル)。
4.2 軸の設定
軸の表示範囲、目盛りの位置、ラベル、グリッドなどを制御できます。
“`python
軸の表示範囲
ax.set_xlim(0, 10)
ax.set_ylim(-1.2, 1.2)
目盛りの位置とラベル
X軸の目盛りを0, π, 2π, … としたい場合
x_ticks = np.arange(0, 11, 2)
x_labels = [f'{i}’ for i in x_ticks] # 例: 文字列ラベル
ax.set_xticks(x_ticks)
ax.set_xticklabels(x_labels) # 目盛りのラベルをリストで指定
Y軸の目盛りを細かくしたい場合
y_ticks = np.arange(-1, 1.1, 0.2)
ax.set_yticks(y_ticks)
グリッドの表示
ax.grid(True, linestyle=’–‘, alpha=0.6) # グリッドを表示、スタイルと透明度を指定
“`
set_xlim
,set_ylim
: 軸の表示範囲を設定します。set_xticks
,set_yticks
: 目盛りの表示位置を数値のリスト/配列で指定します。set_xticklabels
,set_yticklabels
: 目盛りのラベルを文字列のリストで指定します。set_xticks
/set_yticks
の位置に対応するラベルを指定します。grid(True)
: グリッド線を表示します。linestyle
,alpha
,color
などの引数で見た目をカスタマイズできます。
4.3 テキストと注釈
グラフ上の特定のポイントにテキストや矢印付きの注釈を追加することで、重要な情報や特定のデータポイントを強調できます。
“`python
特定の点にテキストを追加
ax.text(np.pi/2, np.sin(np.pi/2), ‘最大値’, fontsize=10, ha=’center’, va=’bottom’)
ha=’center’, va=’bottom’ はテキストの位置揃え (horizontal alignment, vertical alignment)
特定の点に矢印付きの注釈を追加
ax.annotate(‘最小値’, xy=(3np.pi/2, np.sin(3np.pi/2)), xytext=(3*np.pi/2 + 1, -0.5),
arrowprops=dict(facecolor=’black’, shrink=0.05))
“`
ax.text(x, y, text, **kwargs)
: グラフ上の座標(x, y)
にtext
を表示します。fontsize
,color
,ha
(horizontal alignment: ‘left’, ‘center’, ‘right’),va
(vertical alignment: ‘top’, ‘center’, ‘bottom’, ‘baseline’) などの引数があります。ax.annotate(text, xy=(x, y), xytext=(x_text, y_text), arrowprops=dict(...), **kwargs)
: 座標xy
のデータポイントに対して、座標xytext
にtext
を表示し、両者を矢印で結びます。arrowprops
ディクショナリで矢印のスタイルを細かく設定できます。
4.4 色のカスタマイズ
Matplotlibでは、単一の色指定からカラーマップの利用まで、様々な方法で色をカスタマイズできます。
- 単一の色指定: 色の名前 (‘red’, ‘blue’, ‘green’), 16進数 (‘#FF5733’), RGBタプル
(r, g, b)
(各要素は0から1の浮動小数点数) などで指定します。 - カラーマップ (Colormap): 数値データを色のグラデーションにマッピングするために使用します。散布図の
c
引数やヒストグラムのcmap
引数などで利用されます。Matplotlibには多くの組み込みカラーマップがあります(例: ‘viridis’, ‘plasma’, ‘inferno’, ‘magma’, ‘cividis’, ‘Blues’, ‘Greens’, ‘Reds’, ‘hot’, ‘cool’など)。
“`python
カラーマップの例 (散布図)
np.random.seed(0)
x = np.random.rand(100) * 10
y = np.random.rand(100) * 10
colors = np.sqrt(x2 + y2) # 原点からの距離を色にマッピング
fig, ax = plt.subplots()
scatter = ax.scatter(x, y, c=colors, cmap=’viridis’, s=50, alpha=0.8)
fig.colorbar(scatter, label=’距離’) # カラーバーを追加
ax.set_title(‘カラーマップを使った散布図’)
ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
plt.show()
“`
カラーマップの一覧は plt.colormaps()
で取得できます。
4.5 複数グラフの表示 (Subplots)
一つのFigure内に複数のAxes(グラフ)を配置することをサブプロット (Subplots) と呼びます。複数の関連するグラフを並べて表示することで、データの比較や異なる側面の分析を容易に行えます。
サブプロットを作成する最も一般的で推奨される方法は plt.subplots()
関数を使用することです。
“`python
2行1列のサブプロットを作成
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(6, 8)) # (行数, 列数)を指定
axes は Axes オブジェクトの NumPy 配列になる
上のAxes (0番目)
axes[0].plot(x, y1, color=’red’)
axes[0].set_title(‘sin(x)’)
axes[0].set_ylabel(‘y’)
axes[0].grid(True)
下のAxes (1番目)
axes[1].plot(x, y2, color=’blue’)
axes[1].set_title(‘cos(x)’)
axes[1].set_xlabel(‘x’)
axes[1].set_ylabel(‘y’)
axes[1].grid(True)
グラフ間のスペースを自動調整
plt.tight_layout()
plt.show()
“`
plt.subplots(nrows, ncols, figsize=(width, height))
:nrows
行、ncols
列のグリッド状にAxesを配置します。figsize
でFigure全体のサイズを指定できます。戻り値はFigureオブジェクトと、Axesオブジェクトを格納したNumPy配列です。配列の形状は(nrows, ncols)
になります(1行または1列の場合は1次元配列)。
複雑なレイアウト (GridSpec
)
より複雑なレイアウト(例えば、サイズが異なるAxesを配置する)を作成したい場合は、GridSpec
を使用します。
“`python
import matplotlib.gridspec as gridspec
fig = plt.figure(figsize=(9, 6))
gs = gridspec.GridSpec(2, 2) # 2行2列のグリッドを定義
グリッドの指定した範囲にAxesを作成
ax1 = fig.add_subplot(gs[0, :]) # 1行目全体 (0行目の全ての列) を使う
ax2 = fig.add_subplot(gs[1, 0]) # 2行目の1列目 (1行目の0列目) を使う
ax3 = fig.add_subplot(gs[1, 1]) # 2行目の2列目 (1行目の1列目) を使う
各Axesにプロット
ax1.plot(x, y1, color=’red’)
ax2.hist(np.random.randn(100), bins=10)
ax3.scatter(np.random.rand(50), np.random.rand(50))
ax1.set_title(‘Main Plot’)
ax2.set_title(‘Histogram’)
ax3.set_title(‘Scatter Plot’)
plt.tight_layout()
plt.show()
“`
gridspec.GridSpec(nrows, ncols)
でグリッドの構造を定義し、fig.add_subplot(gs[row_slice, col_slice])
で、そのグリッド内の指定した範囲 (row_slice
, col_slice
にスライスを指定) にAxesを配置します。
グラフ間のスペース調整 (tight_layout
, subplots_adjust
)
サブプロット間のタイトルやラベルが重なってしまうのを防ぐために、スペースを調整する必要があります。
plt.tight_layout()
: サブプロット間のスペースを自動的に調整し、要素が重ならないようにします。手軽でよく使われます。plt.subplots_adjust(left=..., right=..., top=..., bottom=..., wspace=..., hspace=...)
: サブプロット間のスペースをより細かく手動で調整したい場合に用います。wspace
は横方向のスペース、hspace
は縦方向のスペースです。
4.6 スタイルシート
Matplotlibには、あらかじめ定義されたスタイルシートがいくつか用意されています。これらを使うと、グラフの色、フォント、グリッドなどの全体的なスタイルを簡単に変更できます。
利用可能なスタイルシートの一覧は plt.style.available
で確認できます。
python
print(plt.style.available)
いくつかの代表的なスタイルシートがあります。「seaborn-v0_8」から始まるものは、データ可視化ライブラリSeabornにインスパイアされたスタイルで、統計グラフに適した見栄えになります。「ggplot」はR言語のggplot2ライブラリ風のスタイルです。
スタイルシートを適用するには、plt.style.use('スタイルシート名')
をプロットコードの前に記述します。
“`python
import matplotlib.pyplot as plt
import numpy as np
スタイルシートを適用
plt.style.use(‘seaborn-v0_8-darkgrid’)
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, y1, label=’sin(x)’)
ax.plot(x, y2, label=’cos(x)’)
ax.set_title(‘サイン・コサイン曲線 (seaborn-darkgridスタイル)’)
ax.set_xlabel(‘x’)
ax.set_ylabel(‘y’)
ax.legend()
plt.show()
“`
スタイルシートは一度適用すると、そのPythonセッション内で作成される全てのグラフに影響します。特定のグラフにだけ適用したい場合は、plt.style.context()
を使用します。
“`python
特定のブロックにだけスタイルを適用する場合
with plt.style.context(‘ggplot’):
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
ax.set_title(‘ggplotスタイル’)
plt.show()
これ以降のグラフはデフォルトスタイルに戻る
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
ax.set_title(‘デフォルトスタイル’)
plt.show()
“`
第5章: 応用的なグラフタイプ
基本的なグラフタイプ以外にも、Matplotlibは様々な応用的なグラフタイプを作成する機能を提供しています。この章では、データの分布や関係性をより詳細に分析・可視化するためのグラフタイプを紹介します。
5.1 箱ひげ図 (Box Plot)
箱ひげ図は、データのばらつきや中心傾向、外れ値を視覚的に示すのに適しています。特に複数のグループ間でこれらの統計量を比較する際に有効です。箱(四分位範囲、IQR)とひげ(最大値・最小値、または外れ値を除く範囲)でデータの要約統計量を示します。
作成方法は plt.boxplot(data)
または ax.boxplot(data)
です。data
には、プロットしたいデータセットのリストまたは配列のリストを指定します。
“`python
import matplotlib.pyplot as plt
import numpy as np
異なるグループのランダムなデータを作成 (例)
np.random.seed(10)
data1 = np.random.normal(100, 10, 200)
data2 = np.random.normal(90, 20, 200)
data3 = np.random.normal(80, 30, 200)
data_to_plot = [data1, data2, data3]
fig, ax = plt.subplots()
ax.boxplot(data_to_plot, labels=[‘Group 1’, ‘Group 2’, ‘Group 3’])
ax.set_title(‘グループ別の箱ひげ図’)
ax.set_ylabel(‘値’)
plt.show()
“`
labels
: 各箱に対応するラベルのリストを指定します。vert=False
とすると横向きの箱ひげ図になります。showfliers=False
とすると外れ値(ひげの外側の点)を非表示にできます。
5.2 バイオリンプロット (Violin Plot)
バイオリンプロットは、箱ひげ図と同様にデータの分布を比較するのに使われますが、箱ひげ図よりも詳細な分布の形状(確率密度)を示します。中央の太い部分がデータの密度の高い領域を表し、その形状から分布のピークや多峰性などを読み取ることができます。
作成方法は plt.violinplot(data)
または ax.violinplot(data)
です。引数 data
の形式は箱ひげ図と同様です。
python
fig, ax = plt.subplots()
ax.violinplot(data_to_plot, showmeans=True, showmedians=True) # 平均値と中央値を表示
ax.set_title('グループ別のバイオリンプロット')
ax.set_xticks(np.arange(1, len(data_to_plot) + 1)) # X軸の目盛り位置
ax.set_xticklabels(['Group 1', 'Group 2', 'Group 3']) # X軸の目盛りラベル
ax.set_ylabel('値')
plt.show()
showmeans
: 平均値を表示するかどうかを指定します。showmedians
: 中央値を表示するかどうかを指定します。
箱ひげ図とバイオリンプロットは、複数のグループのデータの要約統計量や分布の形状を比較する際に非常に有用です。
5.3 ヒートマップ (Heatmap)
ヒートマップは、二次元データの値を色の濃淡で表現するグラフです。特に行列形式のデータ(例えば相関行列や混同行列)の可視化に適しています。色のグラデーションによって、値の大小やパターンを直感的に把握できます。
Matplotlibでヒートマップを作成するには、plt.imshow()
または ax.imshow()
関数を使用するのが一般的です。これは画像を表示するための関数ですが、NumPy配列などを渡すことでヒートマップとして利用できます。より高機能なヒートマップ(目盛りラベルの自動設定、値のテキスト表示など)を作成する場合は、データ可視化ライブラリ Seaborn の seaborn.heatmap()
を使うのが非常に便利で推奨されます(SeabornはMatplotlibをベースに作られています)。ここではMatplotlibの基本機能を使った例を示します。
“`python
import matplotlib.pyplot as plt
import numpy as np
相関行列を模したデータ (例)
data = np.random.rand(10, 10) * 100
fig, ax = plt.subplots()
imshow は画像を表示するが、データ配列を渡すと色の濃淡で表示される
im = ax.imshow(data, cmap=’hot_r’) # ‘hot_r’ はhotカラーマップの逆順
カラーバーを追加
fig.colorbar(im, ax=ax, label=’値’)
ax.set_title(‘シンプルなヒートマップ’)
plt.show()
“`
cmap
: 使用するカラーマップを指定します。ヒートマップでは連続的なカラーマップ(例: ‘viridis’, ‘plasma’, ‘hot’, ‘cool’, ‘Blues’, ‘Reds’など)がよく使われます。末尾に_r
を付けると逆順になります。
目盛りのラベルなどを細かく設定するには、ax.set_xticks
, ax.set_yticks
, ax.set_xticklabels
, ax.set_yticklabels
を使用する必要があります。
5.4 3Dプロット
Matplotlibは、3Dグラフを作成するための基本的な機能も提供しています。3D散布図、3D折れ線グラフ、曲面プロットなどを作成できます。3Dプロットを使用するには、mplot3d
ツールキットをインポートし、Axesを作成する際に projection='3d'
を指定する必要があります。
“`python
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D # 3Dプロットツールキットをインポート
3D Axesを作成
fig = plt.figure()
ax = fig.add_subplot(111, projection=’3d’) # Axesを作成する際に projection=’3d’ を指定
3D散布図のデータ
n = 100
xs = np.random.rand(n) * 10
ys = np.random.rand(n) * 10
zs = np.random.rand(n) * 10
3D散布図
ax.scatter(xs, ys, zs, c=zs, cmap=’viridis’) # cで色を指定
ax.set_xlabel(‘X Label’)
ax.set_ylabel(‘Y Label’)
ax.set_zlabel(‘Z Label’)
ax.set_title(‘3D散布図’)
plt.show()
“`
曲面プロット (plot_surface
)
3D空間における関数の曲面を可視化するのに使用します。
“`python
3D曲面プロットのデータ
x = np.linspace(-5, 5, 50)
y = np.linspace(-5, 5, 50)
X, Y = np.meshgrid(x, y) # グリッドを作成
Z = np.sin(np.sqrt(X2 + Y2))
fig = plt.figure()
ax = fig.add_subplot(111, projection=’3d’)
曲面プロット
surf = ax.plot_surface(X, Y, Z, cmap=’viridis’)
fig.colorbar(surf, ax=ax, label=’Z値’)
ax.set_title(‘3D曲面プロット’)
ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
ax.set_zlabel(‘Z’)
plt.show()
“`
3Dプロットはデータの空間的な関係性を把握するのに役立ちますが、見方によっては情報の読み取りが難しくなることもあります。使用する際は、伝えたい情報が効果的に伝わるかを考慮する必要があります。
5.5 エラーバー付きグラフ
測定値に含まれる誤差やばらつきを示すために、エラーバー付きのグラフを作成することがあります。特に科学実験や調査データなどで用いられます。
plt.errorbar(x, y, yerr, xerr, **kwargs)
または ax.errorbar()
を使用します。yerr
はy方向のエラー、xerr
はx方向のエラーを指定します。
“`python
import matplotlib.pyplot as plt
import numpy as np
データ (例: 実験結果とその誤差)
x = np.array([1, 2, 3, 4, 5])
y = np.array([10, 12, 9, 15, 11])
yerr = np.array([1.5, 2, 1, 2.5, 1.8]) # 各点に対応する誤差
fig, ax = plt.subplots()
ax.errorbar(x, y, yerr=yerr, fmt=’o-‘, label=’実験データ’, capsize=3)
fmt=’o-‘ は、円形マーカーと実線で結ぶことを指定
capsize はエラーバーの端に付けるキャップのサイズ
ax.set_title(‘エラーバー付き折れ線グラフ’)
ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
ax.legend()
ax.grid(True)
plt.show()
“`
エラーバー付きグラフは、データの信頼性やばらつきの大きさを伝えるのに役立ちます。
第6章: 実際のデータを使ったケーススタディ
ここまで、Matplotlibの基本的な使い方や様々なグラフタイプの作成方法、カスタマイズについて学んできました。しかし、実際のデータ分析では、生データをそのままプロットすることは少なく、多くの場合、データの読み込み、前処理、集計といったステップが必要です。
この章では、Pythonの強力なデータ分析ライブラリ Pandas を使用してデータを読み込み、簡単な前処理を行い、Matplotlibと連携して実際のデータセットを可視化する例を示します。Pandasはデータ操作に非常に便利であり、Matplotlibとの連携もスムーズです。
6.1 CSVファイルの読み込み(Pandasの利用を推奨)
CSV (Comma Separated Values) ファイルは、表形式データを保存する最も一般的な形式の一つです。Pandasを使うと、CSVファイルを簡単にDataFrameという便利なデータ構造に読み込むことができます。
“`python
import pandas as pd
例として、以下の内容のCSVファイル ‘sample_data.csv’ を作成したとします。
Name,Age,City,Salary
Alice,30,New York,60000
Bob,25,Los Angeles,55000
Charlie,35,Chicago,70000
David,28,New York,62000
Eve,32,Los Angeles,65000
CSVファイルを読み込み
try:
df = pd.read_csv(‘sample_data.csv’)
print(“CSVファイルを読み込みました。”)
print(df.head()) # 最初の5行を表示
except FileNotFoundError:
print(“sample_data.csv が見つかりません。ダミーデータを作成します。”)
# ファイルが見つからない場合はダミーデータを作成
data = {‘Name’: [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’, ‘Eve’, ‘Frank’, ‘Grace’, ‘Heidi’, ‘Ivy’, ‘Jack’],
‘Age’: [30, 25, 35, 28, 32, 45, 22, 38, 29, 41],
‘City’: [‘New York’, ‘Los Angeles’, ‘Chicago’, ‘New York’, ‘Los Angeles’, ‘Chicago’, ‘New York’, ‘Los Angeles’, ‘Chicago’, ‘New York’],
‘Salary’: [60000, 55000, 70000, 62000, 65000, 80000, 50000, 75000, 68000, 85000]}
df = pd.DataFrame(data)
print(df.head())
“`
pd.read_csv('ファイル名.csv')
だけで、データがDataFrameとしてメモリに読み込まれます。DataFrameは、列名を持つ二次元の表形式データであり、各列はSeriesという一次元データ構造です。
6.2 データの前処理(簡単なもの)
実際のデータには、欠損値があったり、データ型が適切でなかったりすることがあります。可視化の前に簡単な前処理が必要になることがあります。
- 欠損値の確認:
df.isnull().sum()
で各列の欠損値の数を確認できます。 - 欠損値の処理:
df.dropna()
で欠損値を含む行を削除したり、df.fillna(value)
で欠損値を特定の値で埋めたりします。 - データ型の変換:
df['列名'].astype('新しい型')
で列のデータ型を変換できます(例: ‘int’, ‘float’, ‘datetime’)。
ここでは簡単な例なので、欠損値やデータ型変換は行いませんが、実際のデータ分析では重要なステップです。
6.3 Pandasとの連携 (.plot()
メソッド)
Pandas DataFrameやSeriesは、Matplotlibを内部で利用した .plot()
メソッドを提供しています。これを使うと、Pandasでデータ操作した結果を非常に簡単にグラフ化できます。多くの場合、df.plot(kind='...')
のように使います。
“`python
Pandas DataFrameの .plot() メソッドを使ったグラフ作成例
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
ダミーデータの再作成(もしファイルがなければ)
try:
df = pd.read_csv(‘sample_data.csv’)
except FileNotFoundError:
data = {‘Name’: [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’, ‘Eve’, ‘Frank’, ‘Grace’, ‘Heidi’, ‘Ivy’, ‘Jack’],
‘Age’: [30, 25, 35, 28, 32, 45, 22, 38, 29, 41],
‘City’: [‘New York’, ‘Los Angeles’, ‘Chicago’, ‘New York’, ‘Los Angeles’, ‘Chicago’, ‘New York’, ‘Los Angeles’, ‘Chicago’, ‘New York’],
‘Salary’: [60000, 55000, 70000, 62000, 65000, 80000, 50000, 75000, 68000, 85000]}
df = pd.DataFrame(data)
例1: 年齢と給与の散布図
df.plot(kind=’scatter’, x=’Age’, y=’Salary’, title=’年齢と給与の関係’)
plt.show()
例2: 都市別の平均給与を棒グラフで表示
まず都市別に平均給与を集計
city_salary = df.groupby(‘City’)[‘Salary’].mean()
print(“\n都市別平均給与:”)
print(city_salary)
集計結果を棒グラフ化
city_salary.plot(kind=’bar’, title=’都市別の平均給与’)
plt.ylabel(‘平均給与’) # y軸ラベルは別途追加
plt.xticks(rotation=0) # x軸のラベルを回転させない
plt.tight_layout() # ラベルが重ならないように調整
plt.show()
例3: 給与の分布をヒストグラムで表示
df[‘Salary’].plot(kind=’hist’, bins=5, title=’給与の分布’)
plt.xlabel(‘給与’) # x軸ラベルは別途追加
plt.ylabel(‘度数’) # y軸ラベルは別途追加
plt.show()
“`
.plot()
メソッドは、kind
引数でグラフの種類を指定します(’line’, ‘bar’, ‘barh’, ‘hist’, ‘box’, ‘kde’, ‘density’, ‘area’, ‘pie’, ‘scatter’, ‘hexbin’ など)。多くの基本的なグラフタイプに対応しています。Pandasの .plot()
は内部でMatplotlibのFigureとAxesを作成し、データをプロットしてくれます。より細かいカスタマイズが必要な場合は、matplotlib.pyplot
や Axes オブジェクトを直接操作します。.plot()
メソッドは Axes オブジェクトを返すため、その後続けてMatplotlibのメソッドを呼び出すことも可能です。
“`python
Pandas .plot() と Matplotlib を組み合わせる例
ax = df.plot(kind=’scatter’, x=’Age’, y=’Salary’, title=’年齢と給与の関係’)
ax.grid(True, linestyle=’–‘, alpha=0.6) # MatplotlibのAxesメソッドでグリッドを追加
plt.show()
“`
6.4 具体的なデータセットを使った分析と可視化
ここでは、より実践的な例として、データサイエンスの学習でよく使われる「アヤメのデータセット (Iris dataset)」や簡単な時系列データを使ってみましょう。
例1: アヤメのデータセット – 特徴量間の関係性を散布図で可視化
アヤメのデータセットには、3種類のアヤメ(setosa, versicolor, virginica)について、がく片の長さ(sepal length)、がく片の幅(sepal width)、花弁の長さ(petal length)、花弁の幅(petal width)という4つの特徴量が記録されています。これらの特徴量間の関係性や、種類による違いを可視化してみます。
“`python
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris # scikit-learnからアヤメデータをロード
アヤメのデータセットをロード
iris = load_iris()
DataFrameに変換
df_iris = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df_iris[‘species’] = iris.target # ターゲット変数(種類)を追加
数値のターゲット変数を種類名に変換
df_iris[‘species_names’] = df_iris[‘species’].map({0: ‘setosa’, 1: ‘versicolor’, 2: ‘virginica’})
print(“アヤメデータセットの最初の5行:”)
print(df_iris.head())
特徴量間の散布図行列を作成
seabornを使わない場合、サブプロットとscatterを組み合わせる
features = [‘sepal length (cm)’, ‘sepal width (cm)’, ‘petal length (cm)’, ‘petal width (cm)’]
n_features = len(features)
fig, axes = plt.subplots(n_features, n_features, figsize=(10, 10))
plt.style.use(‘seaborn-v0_8-whitegrid’) # スタイルを適用
colors = [‘navy’, ‘turquoise’, ‘darkorange’] # 種別ごとの色
for i in range(n_features):
for j in range(n_features):
ax = axes[i, j]
if i == j:
# 対角線上にヒストグラムや密度プロット (ここではシンプルにタイトル表示)
ax.text(0.5, 0.5, features[i].replace(‘ (cm)’, ”).replace(‘ ‘, ‘\n’),
horizontalalignment=’center’, verticalalignment=’center’,
fontsize=10, transform=ax.transAxes)
ax.set_xticks([])
ax.set_yticks([])
ax.spines[‘top’].set_visible(False)
ax.spines[‘right’].set_visible(False)
ax.spines[‘left’].set_visible(False)
ax.spines[‘bottom’].set_visible(False)
else:
# 対角線以外に散布図
for color, i_species, species_name in zip(colors, [0, 1, 2], iris.target_names):
# 特定の種類のデータだけを抽出してプロット
ax.scatter(df_iris.loc[df_iris[‘species’] == i_species, features[j]],
df_iris.loc[df_iris[‘species’] == i_species, features[i]],
color=color, alpha=.8, label=species_name, s=20) # sは点のサイズ
# ラベル設定 (一番外側のグラフのみ)
if ax.is_last_row():
ax.set_xlabel(features[j].replace(' (cm)', ''), fontsize=8)
else:
ax.set_xlabel("")
ax.tick_params(labelbottom=False) # ラベル非表示
if ax.is_first_col():
ax.set_ylabel(features[i].replace(' (cm)', ''), fontsize=8)
else:
ax.set_ylabel("")
ax.tick_params(labelleft=False) # ラベル非表示
凡例をFigureの外にまとめて表示
handles, labels = axes[0, 1].get_legend_handles_labels() # どれか一つのAxesから凡例情報を取得
fig.legend(handles, labels, loc=’lower right’, bbox_to_anchor=(1, 0, 0.1, 1)) # Figure全体の凡例として表示
plt.tight_layout(rect=[0, 0, 0.95, 1]) # 凡例のためのスペースを確保してレイアウト調整
plt.suptitle(‘アヤメデータセット – 特徴量間の散布図行列’, y=1.02) # Figure全体のタイトル
plt.show()
補足: seaborn.pairplot を使うと、この散布図行列は1行のコードで作成できます。
import seaborn as sns
sns.pairplot(df_iris.drop(‘species’, axis=1), hue=’species_names’)
plt.show()
“`
この例は少し複雑ですが、複数のサブプロットを作成し、データフレームから特定の条件を満たすデータを抽出してプロットする方法、そしてラベルやタイトル、凡例を細かく設定する方法を示しています。
例2: 簡単な時系列データの可視化
ランダムなノイズを含む時系列データを生成し、折れ線グラフで可視化します。
“`python
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
時系列データの生成
dates = pd.date_range(‘20230101’, periods=100)
data = np.random.randn(100).cumsum() + 50 # 累積和でトレンドを表現 + 基準値
df_ts = pd.DataFrame(data, index=dates, columns=[‘Value’])
print(“\n時系列データセットの最初の5行:”)
print(df_ts.head())
折れ線グラフでプロット (Pandas .plot() を使用)
時系列データのインデックスが自動的にx軸になります
ax = df_ts.plot(kind=’line’, figsize=(10, 6), title=’時系列データの推移’)
ax.set_xlabel(‘日付’)
ax.set_ylabel(‘値’)
ax.grid(True)
plt.show()
“`
Pandas DataFrameのインデックスが日付型の場合、.plot()
は自動的にX軸を時系列として適切に扱ってくれます。
これらのケーススタディは、実際のデータ分析ワークフローにおけるMatplotlibの利用例の一部を示しています。Pandasと組み合わせることで、データの準備から可視化までを効率的に行うことができます。
第7章: さらに進んだトピック
Matplotlibは非常に奥が深く、ここで紹介しきれないほど多くの機能を持っています。この章では、さらに進んだトピックとして、グラフのアニメーション、インタラクティブなグラフ、他のライブラリとの連携、そしてMatplotlibを使う上での注意点について簡単に触れます。
7.1 アニメーションの作成(簡単な紹介)
Matplotlibはグラフのアニメーションを作成する機能も提供しています。これは、データの変化を時間軸に沿って見せたい場合などに有効です。matplotlib.animation
モジュールを使用します。
アニメーションの作成には、通常以下のステップが必要です。
1. Figureオブジェクトを作成する。
2. プロットする初期状態を作成する。
3. アニメーションの各フレームを更新する関数を定義する。この関数は、新しいデータでプロットを更新し、変更されたアーティストオブジェクトを返す。
4. animation.FuncAnimation
オブジェクトを作成し、Figure、更新関数、フレーム数などを指定する。
5. アニメーションを表示または保存する (plt.show()
, anim.save()
)。
これはやや複雑なトピックであり、この記事の範囲を大きく超えるため、ここでは簡単なコード例のみを示します。詳細については、Matplotlibの公式ドキュメントを参照してください。
“`python
アニメーションの簡単な例 (Jupyter環境で実行する場合は適切なバックエンドが必要)
%matplotlib notebook または %matplotlib widget
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = ax.plot([], [], ‘ro-‘) # プロットするラインオブジェクトを作成 (戻り値はタプルのためカンマが必要)
def init():
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1.1, 1.1)
return ln, # 更新されたオブジェクトを返す
def update(frame):
xdata.append(frame)
ydata.append(np.sin(frame))
ln.set_data(xdata, ydata) # データの更新
return ln,
アニメーションを作成
ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
init_func=init, blit=True) # blit=True で高速化
Jupyter Notebook/Lab でインタラクティブに表示する場合は %matplotlib notebook/widget を使用
一般的なPythonスクリプトでウィンドウ表示する場合は plt.show()
plt.show()
アニメーションの保存 (例: GIFとして保存)
requires imagemagick or ffmpeg
ani.save(‘sine_wave.gif’, writer=’imagemagick’)
print(“アニメーションを保存しました: sine_wave.gif”)
注: アニメーションの実行と保存には追加のライブラリが必要な場合があります。
“`
アニメーションはデータを動的に見せる powerful な方法ですが、実装には少し手間がかかります。
7.2 インタラクティブなグラフ
Jupyter Notebook/Labなどの環境では、Matplotlibのグラフをインタラクティブに操作することができます。例えば、グラフの拡大・縮小、パン(平行移動)、データポイントへのマウスカーソル合わせによる情報表示などが可能です。
Jupyter環境でインタラクティブなグラフを利用するには、適切なマジックコマンドを最初に実行します。
%matplotlib notebook
: 古いですが、一部の環境で動作します。グラフがNotebook内に埋め込まれ、インタラクティブに操作できます。%matplotlib widget
(または%matplotlib ipympl
): 新しいインタラクティブバックエンドです。JupyterLabやJupyter Notebookでより安定して動作し、拡大・縮小などの操作が可能です。利用するにはpip install ipympl
またはconda install ipympl
でipympl
ライブラリのインストールが必要です。
“`python
Jupyter環境で実行する場合
%matplotlib widget
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_title(‘インタラクティブなグラフ’)
plt.xlabel(‘X’)
plt.ylabel(‘Y’)
%matplotlib widget を実行していれば、このセルを実行するとインタラクティブなグラフが表示される
plt.show() は不要
“`
インタラクティブな機能は、データの探索的な分析において非常に役立ちます。
7.3 他のライブラリとの連携
MatplotlibはPythonのデータ可視化エコシステムの基盤となっています。多くの他のライブラリがMatplotlibの上に構築されており、Matplotlibと連携して動作します。
- Pandas: 前述のように、DataFrameやSeriesの
.plot()
メソッドは内部でMatplotlibを使用しており、データ操作からグラフ作成までをスムーズに行えます。 - Seaborn: Matplotlibをベースにした統計的データ可視化ライブラリです。より洗練されたデフォルトスタイルを持ち、複雑な統計グラフ(分布プロット、カテゴリ別プロット、相関ヒートマップなど)を簡単に作成できます。Seabornで作成したグラフも、MatplotlibのAxesオブジェクトとして返されるため、Matplotlibの関数やメソッドを使ってさらにカスタマイズすることが可能です。
- Plotly, Bokeh: Webブラウザ上でインタラクティブなグラフを作成するためのライブラリです。Matplotlibとは異なる描画エンジンを使用しますが、Pythonでグラフを作成できる点では共通しています。Webアプリケーションやダッシュボードでの利用に適しています。
データ可視化の目的や状況に応じて、これらのライブラリとMatplotlibを組み合わせて使うのが一般的です。例えば、統計グラフの作成はSeabornで行い、その Axes オブジェクトに対してMatplotlibで注釈を追加するといったワークフローが考えられます。
7.4 Matplotlibで避けるべき落とし穴
Matplotlibを使う上で、特に初心者が陥りがちな注意点があります。
- Pyplot API と オブジェクト指向 API の混在: 同じグラフに対して、
plt.xlabel()
とax.set_xlabel()
のように両方のAPIの関数を混在させると、意図しない動作になる可能性があります。単一のシンプルなグラフならPyplot、複数のグラフや複雑なカスタマイズをするならオブジェクト指向API、と使い分けるのが推奨されます。オブジェクト指向APIを使う場合は、plt.subplots()
で Figure と Axes を取得し、Axesのメソッド (ax.plot
,ax.set_title
など) を使うように統一しましょう。 - Figure と Axes の関係性の理解不足: 複数のグラフを扱う際に、今操作しているのがどのAxesなのかを意識しないと、意図しない場所にプロットしてしまったり、設定が反映されなかったりします。
plt.subplots()
を使ってAxesオブジェクトを取得し、明示的に操作することでこの問題を避けられます。 - グラフを表示し忘れる: Pythonスクリプトとして実行する場合、グラフを表示するためには
plt.show()
を最後に呼び出す必要があります。Jupyter環境では多くの場合不要ですが、スクリプトで書く際には忘れずに記述しましょう。 - 日本語表示の問題: デフォルトの設定では、グラフ中に日本語を表示すると文字化けすることがあります。これは使用しているフォントに日本語グリフが含まれていないためです。フォントを設定することで解決できます(例:
plt.rcParams['font.family'] = 'IPAexGothic'
など、使用したい日本語フォントを指定)。
第8章: グラフのエクスポート
作成したグラフは、レポートやプレゼンテーション、Webサイトなどに使用するために画像ファイルとして保存するのが一般的です。Matplotlibでは、様々な形式でグラフを保存できます。
グラフをファイルに保存するには、plt.savefig('ファイル名.拡張子', **kwargs)
または fig.savefig('ファイル名.拡張子', **kwargs)
を使用します。Figureオブジェクトを取得している場合は、fig.savefig()
を使うのがより明示的で推奨されます。
“`python
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(figsize=(8, 5))
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x))
ax.set_title(‘保存するグラフ’)
ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
グラフをファイルに保存
fig.savefig(‘sine_wave.png’) # PNG形式で保存
print(“グラフを sine_wave.png として保存しました。”)
fig.savefig(‘sine_wave.jpg’, dpi=300) # JPEG形式で、解像度300dpiで保存
print(“グラフを sine_wave.jpg (300dpi) として保存しました。”)
fig.savefig(‘sine_wave.pdf’) # PDF形式で保存 (ベクター画像として保存されることが多い)
print(“グラフを sine_wave.pdf として保存しました。”)
fig.savefig(‘sine_wave.svg’) # SVG形式で保存 (Webや編集に適したベクター画像)
print(“グラフを sine_wave.svg として保存しました。”)
グラフ表示の前に保存する (保存後に plt.show() を呼ぶのが一般的)
plt.show()
“`
- ファイル形式: 拡張子 (
.png
,.jpg
,.pdf
,.svg
など) を指定することで、様々な形式で保存できます。PNGやJPEGはビットマップ画像、PDFやSVGはベクター画像です。ベクター画像は拡大しても劣化しないため、印刷や編集に適しています。 - 解像度 (
dpi
): ビットマップ画像(PNG, JPEGなど)を保存する際の解像度をドット/インチで指定します。高い値を指定すると、より高精細な画像になりますが、ファイルサイズも大きくなります。印刷用途などでは300 dpi以上が推奨されます。 - 余白の調整 (
bbox_inches
): グラフの周囲の不要な余白を削除して保存したい場合は、bbox_inches='tight'
を指定します。 - 透明度 (
transparent
): 背景を透明にして保存したい場合は、transparent=True
を指定します(PNGやSVGなど、透明度をサポートする形式でのみ有効です)。
“`python
余白を削除して、背景を透明に保存する例
fig.savefig(‘sine_wave_tight.png’, bbox_inches=’tight’, transparent=True, dpi=300)
print(“グラフを sine_wave_tight.png (余白なし、透明背景) として保存しました。”)
“`
グラフを保存する際には、これらのオプションを適切に設定することで、目的に合った高品質な画像ファイルを得ることができます。
まとめ
この記事では、PythonのMatplotlibライブラリを使ったデータ可視化について、準備から基本的なグラフ作成、カスタマイズ、応用、そして実際のデータを使った例、さらには保存方法まで、幅広く詳細に解説しました。
Matplotlibは、Pythonで質の高いグラフを作成するための非常に強力で柔軟なツールです。Pyplot APIを使えば手軽にグラフを作成でき、オブジェクト指向APIを使えばグラフのあらゆる要素を細かく制御できます。折れ線グラフ、散布図、棒グラフ、ヒストグラム、円グラフといった基本的なグラフから、箱ひげ図、バイオリンプロット、ヒートマップ、3Dプロットなどの応用的なグラフまで、様々な種類のグラフを扱えることも魅力です。
データ分析において、可視化はデータを理解し、分析結果を共有するために不可欠なステップです。Matplotlibを使いこなすことで、あなたはデータが語る物語を視覚的に表現し、より多くの人々に伝えることができるようになります。
学んだ内容の振り返り
- Matplotlibのインストールと環境設定
- FigureとAxesの基本概念
- Pyplot APIとオブジェクト指向APIの使い分け
- 折れ線グラフ、散布図、棒グラフ、ヒストグラム、円グラフの作成方法
- タイトル、ラベル、凡例、軸などのカスタマイズ方法
- 複数グラフ(サブプロット)の表示と制御
- スタイルシートを使った全体のスタイリング
- 箱ひげ図、バイオリンプロット、ヒートマップ、3Dプロット、エラーバーなどの応用的なグラフタイプ
- Pandasを使ったデータの読み込みと、
.plot()
メソッドによる簡単な連携 - 実際のデータセットを使った可視化の例
- アニメーションやインタラクティブ機能、他のライブラリとの連携についての紹介
- グラフのエクスポート方法
Matplotlib活用のヒント
- 目的を明確にする: 何を伝えたいグラフなのかを考え、それに最適なグラフタイプを選びましょう。
- シンプルに保つ: 情報を詰め込みすぎず、分かりやすさを最優先にしましょう。
- 適切にラベルを付ける: タイトル、軸ラベル、凡例は、グラフの内容を正確に伝えるために不可欠です。
- 色を効果的に使う: 色には意味を持たせたり、重要な要素を強調したりする役割があります。ただし、色の使いすぎや、色覚多様性への配慮も忘れずに。
- 試行錯誤を恐れない: 完璧なグラフは一度にできるものではありません。様々なオプションやスタイルを試しながら、目的の表現に近づけていきましょう。Jupyter環境を使えば、インタラクティブに試しながら進めることができます。
次のステップ
この記事で紹介した内容は、Matplotlibの機能のごく一部に過ぎません。さらに深くMatplotlibを使いこなすためには、以下のリソースが役立ちます。
- Matplotlib公式ドキュメント: Matplotlibの全ての機能に関する詳細な情報源です。少し難解な部分もありますが、リファレンスとして非常に重要です。
- Matplotlib Gallery: 様々なグラフタイプのコード例が豊富に掲載されています。作りたいグラフのイメージに近いものを探し、コードを参考にすることから始めるのがおすすめです。
- Seaborn: 統計グラフに特化したライブラリです。Matplotlibよりも簡単に美しい統計グラフを作成できます。データ分析においてはMatplotlibとセットで使われることが非常に多いです。
- Pandas Visualization: Pandasの公式ドキュメントには、DataFrameの
.plot()
メソッドに関する詳細な情報が掲載されています。
データ可視化のスキルは、どのような分野であってもあなたのデータ活用能力を向上させる強力な武器となります。ぜひ Matplotlib を活用して、データの世界を視覚的に探索し、新しい発見を楽しんでください!