Python Matplotlib 入門:グラフ作成とデータ可視化の基本

Python Matplotlib 入門:グラフ作成とデータ可視化の基本

はじめに

データは現代社会における貴重な資産です。しかし、生のデータの羅列だけでは、その中に隠されたパターンや洞察を理解することは困難です。ここでデータ可視化の力が発揮されます。データを視覚的に表現することで、複雑な情報も直感的かつ効率的に把握できるようになります。グラフ、チャート、マップなどは、データ分析の結果を伝えるための強力なツールです。

データ可視化は、科学研究からビジネスレポート、ジャーナリズムに至るまで、あらゆる分野で不可欠なスキルとなっています。Pythonには、データ可視化のための優れたライブラリがいくつか存在しますが、その中でも最も基本的で強力なのがMatplotlibです。

Matplotlibは、Pythonで静的、対話的、さらにはアニメーションのグラフを作成するための包括的なライブラリです。基本的な2Dグラフから複雑な3Dプロットまで、幅広い種類のグラフを作成できます。Pandas、NumPy、SciPyなどの他の科学計算ライブラリとの連携も容易であり、Pythonを使ったデータ分析ワークフローの中心的な役割を果たしています。

この記事では、Matplotlibを使ったグラフ作成とデータ可視化の基本について、詳細かつ実践的な解説を行います。Matplotlibの基本概念から始め、様々な種類のグラフの作成方法、そしてグラフのカスタマイズ技術までを網羅的に学びます。約5000語というボリュームで、Matplotlibの強力な機能を使いこなすための知識をしっかりと身につけることを目指します。

対象読者は、Pythonの基本的な文法を理解しており、データ可視化に興味がある方、あるいは既にMatplotlibを使ったことがあるが、さらに理解を深めたい方です。この記事を通じて、Matplotlibを使ったデータ可視化の基礎を固め、自身のデータ分析能力をさらに向上させることができるでしょう。

さあ、Matplotlibの世界へ足を踏み入れ、データの隠された物語を可視化してみましょう!

Matplotlibの基本概念

Matplotlibを使い始める前に、いくつかの重要な概念を理解しておく必要があります。これにより、コードの構造や、なぜ特定のメソッドを使うのかが明確になります。

主要なコンポーネント:FigureとAxes

Matplotlibのグラフ構造を理解する上で最も重要なのが、FigureAxesという二つの要素です。例えるなら、Figureは「キャンバス」全体であり、Axesは「個々のグラフを描く領域」です。

  • Figure: これは描画されるすべてのグラフ要素を含む最上位のコンテナです。ウィンドウ全体や、印刷されるページの領域に対応します。一つのFigureの中に、複数のAxesを配置することができます。タイトル、全体のサイズ、解像度などを設定するのはFigureオブジェクトに対して行います。
  • Axes: これは実際にデータがプロットされる領域です。X軸とY軸(3Dの場合はZ軸も)を持ち、目盛り、ラベル、タイトル、凡例などのグラフ要素を含みます。一つのFigureは一つまたは複数のAxesを持つことができます。ほとんどのプロット関数(plot(), scatter(), bar()など)は、Axesオブジェクトのメソッドとして呼び出されます。

このFigureとAxesの関係は、特に複数のグラフを一度に表示する場合や、グラフの細かい要素を制御する場合に非常に重要になります。

オブジェクト指向APIとpyplot APIの違い

Matplotlibには主に二つの使い方、またはAPI(Application Programming Interface)があります。

  1. pyplot API: matplotlib.pyplotモジュールをインポートして使用する方法です。これは、MATLABに似たコマンドスタイルの関数を提供します。たとえば、plt.plot(), plt.xlabel(), plt.title()のように、状態機械的に現在のFigureやAxesに対して操作を行います。手軽に素早くグラフを作成したい場合に便利ですが、複雑なレイアウトや細かい制御には向かないことがあります。特に複数のAxesを操作する場合には、どのAxesが現在アクティブなのかを意識する必要があり、コードが読みにくくなることがあります。
  2. オブジェクト指向API: FigureオブジェクトとAxesオブジェクトを明示的に作成し、それらのオブジェクトのメソッドを呼び出してグラフを操作する方法です。たとえば、fig, ax = plt.subplots(), ax.plot(), ax.set_xlabel(), ax.set_title()のように使います。こちらはコードがより構造化され、どのAxesを操作しているのかが明確になります。複雑なグラフや複数のサブプロットを作成する場合には、オブジェクト指向APIを使用することが強く推奨されます。

この記事では、より柔軟で推奨されているオブジェクト指向APIを中心に解説を進めます。しかし、簡単なグラフ作成のためにpyplot APIも適宜紹介します。

基本的な使い方:インポート、FigureとAxesの作成

Matplotlibを使うためには、まずライブラリをインポートします。慣習として、matplotlib.pyplotモジュールはpltという別名でインポートされます。また、NumPyを使ってデータを準備することも多いため、NumPyもインポートしておくと良いでしょう。

python
import matplotlib.pyplot as plt
import numpy as np

次に、オブジェクト指向APIを使ってFigureとAxesを作成する基本的な方法を見てみましょう。最も一般的な方法は、plt.subplots()関数を使うことです。この関数は、新しいFigureと、そのFigure内に一つまたは複数のAxesを作成し、それらを返します。

“`python

FigureとAxesを一つだけ作成する場合

fig, ax = plt.subplots()

Figure内に2×2の4つのAxesを作成する場合

fig, axes = plt.subplots(nrows=2, ncols=2)

この場合、axesはAxesオブジェクトのNumPy配列になります。

各Axesは axes[0, 0], axes[0, 1], axes[1, 0], axes[1, 1] のようにアクセスします。

“`

plt.subplots()は、デフォルトでは一つのFigureと一つのAxesを作成します。返り値はタプルで、最初の要素がFigureオブジェクト、二番目の要素がAxesオブジェクトです。通常、これらをそれぞれfigaxという変数名で受け取ります。

Axesオブジェクト(ax)が作成できたら、このオブジェクトのメソッドを使ってデータをプロットしたり、軸の設定を行ったりします。

グラフを表示するには、plt.show()関数を呼び出す必要があります。これは、作成したFigureウィンドウを開き、グラフを表示するコマンドです。スクリプトの最後に一度だけ呼び出すのが一般的です。

“`python

何らかのプロット処理(ax.plot()など)…

plt.show()
“`

対話的な環境(Jupyter Notebookなど)では、plt.show()を明示的に呼び出さなくてもグラフが表示される場合がありますが、スクリプトとして実行する際は必要です。また、Jupyter Notebookではマジックコマンド%matplotlib inlineを使うことで、セル内に静的なグラフを埋め込むことができます(これはpyplot APIに近い振る舞いをします)。しかし、オブジェクト指向APIを使う場合でも、plt.show()なしにセル実行でグラフが表示されるのが一般的です。

これで、Matplotlibを使うための基本的な準備が整いました。次のセクションでは、実際のデータを使って最初のグラフを作成してみましょう。

最初のグラフ作成

Matplotlibを使って最も基本的でよく使われるグラフの種類を作成する方法を学びます。

シンプルな折れ線グラフ (Line Plot)

折れ線グラフは、時間の経過に伴う変化や、連続的なデータの傾向を示すのに適しています。

データの準備

簡単な折れ線グラフを作成するために、NumPyを使ってサンプルデータ(例えばサインカーブ)を生成します。

“`python

データを生成

x = np.linspace(0, 10, 100) # 0から10までの値を100個生成
y = np.sin(x) # xに対するsinの値を計算
“`

np.linspace()は、指定された開始値と終了値の間を、指定された数の要素で均等に分割した配列を作成します。

ax.plot()の使い方

作成したFigureとAxesオブジェクト(fig, ax)を使って、Axes上に折れ線グラフを描画します。

“`python
fig, ax = plt.subplots()

折れ線グラフを描画

ax.plot(x, y)

グラフを表示

plt.show()
“`

ax.plot(x, y)は、xの値を横軸に、yの値を縦軸にして、点(x[i], y[i])を線で結んだグラフを描画します。

ラベル、タイトル、凡例の追加

グラフに適切なラベル、タイトル、凡例を追加することは、グラフを理解しやすくするために非常に重要です。これらはすべてAxesオブジェクトのメソッドを使って設定します。

“`python
fig, ax = plt.subplots()

ax.plot(x, y, label=’sin(x)’) # label引数で凡例に表示する名前を指定

軸ラベルを設定

ax.set_xlabel(‘X軸の値’)
ax.set_ylabel(‘Y軸の値’)

タイトルを設定

ax.set_title(‘シンプルなサインカーブ’)

凡例を表示

ax.legend()

グラフを表示

plt.show()
“`

  • ax.set_xlabel()ax.set_ylabel():それぞれの軸のラベルを設定します。
  • ax.set_title():Axesのタイトルを設定します。
  • ax.legend()ax.plot()や他のプロット関数でlabel引数が指定されている場合、その凡例を表示します。

グリッドの表示

グラフの値を読み取りやすくするために、グリッド線を表示することができます。

“`python
fig, ax = plt.subplots()

ax.plot(x, y, label=’sin(x)’)

ax.set_xlabel(‘X軸の値’)
ax.set_ylabel(‘Y軸の値’)
ax.set_title(‘シンプルなサインカーブ’)
ax.legend()

グリッドを表示

ax.grid(True)

plt.show()
“`

ax.grid(True)でグリッドが表示されます。引数なしでax.grid()とすると、現在の状態(表示/非表示)を切り替えます。axis='x', axis='y'のように引数で特定の軸のみにグリッドを表示することも可能です。

グラフの保存 (plt.savefig())

作成したグラフを画像ファイルとして保存するには、plt.savefig()関数を使います。これはplt.show()を呼び出す前に実行する必要があります。

“`python
fig, ax = plt.subplots()

ax.plot(x, y, label=’sin(x)’)

ax.set_xlabel(‘X軸の値’)
ax.set_ylabel(‘Y軸の値’)
ax.set_title(‘シンプルなサインカーブ’)
ax.legend()
ax.grid(True)

グラフをPNGファイルとして保存

plt.savefig(‘sine_wave.png’)

保存後にグラフを表示

plt.show()
“`

plt.savefig()にファイル名を指定するだけで、その拡張子に応じた形式で保存されます。.png, .jpg, .svg, .pdfなど、様々な形式に対応しています。解像度を指定したい場合はdpi引数を使います(例: plt.savefig('sine_wave.png', dpi=300))。

散布図 (Scatter Plot)

散布図は、二つの数値変数の関係を示すのに適しています。各データポイントは、二つの変数の値に対応する座標に点として描画されます。

ax.scatter()の使い方

散布図はax.scatter()メソッドを使って作成します。

“`python

サンプルデータを生成

np.random.seed(0) # 乱数のシードを固定
x = np.random.rand(50) * 10 # 0から10の間の乱数50個
y = np.random.rand(50) * 10

fig, ax = plt.subplots()

散布図を描画

ax.scatter(x, y)

ax.set_xlabel(‘X軸の値’)
ax.set_ylabel(‘Y軸の値’)
ax.set_title(‘シンプルな散布図’)

plt.show()
“`

マーカーの種類、色、サイズの変更

散布図の点は、マーカーの種類、色、サイズなどをカスタマイズできます。これらの設定はax.scatter()の引数で指定します。

“`python

サンプルデータを生成

np.random.seed(0)
x = np.random.rand(50) * 10
y = np.random.rand(50) * 10
colors = np.random.rand(50) # 各点の色を指定するための値
sizes = (np.random.rand(50) * 20)**2 # 各点のサイズを指定するための値 (サイズは面積に対応するため二乗)

fig, ax = plt.subplots()

散布図を描画

s: サイズ (area)

c: 色 (color)

marker: マーカーの種類 (‘o’は円、’^’は三角形など)

alpha: 透明度 (0.0から1.0)

ax.scatter(x, y, s=sizes, c=colors, marker=’o’, alpha=0.5, cmap=’viridis’) # cmapはカラーマップを指定

ax.set_xlabel(‘X軸の値’)
ax.set_ylabel(‘Y軸の値’)
ax.set_title(‘カスタマイズされた散布図’)

カラーマップを使用した場合はカラーバーを追加すると分かりやすい

fig.colorbar(scatter, ax=ax, label=’色の意味’) # scatterはax.scatterの戻り値として受け取るのが正式だが、ここでは簡単化

plt.show()
“`

  • s: マーカーのサイズを指定します。通常、これは点の面積に対応します。
  • c: マーカーの色を指定します。単一の色名やHEXコードを指定することもできますが、数値の配列を渡すと、その数値に応じてカラーマップが適用され、点の色の違いで第三の変数を示すことができます。
  • marker: マーカーの形状を指定します。例えば'o'(円)、'x'(X)、'^'(上向き三角形)などがあります。利用可能なマーカーの種類はMatplotlibのドキュメントで確認できます。
  • alpha: マーカーの透明度を指定します。0.0(完全透明)から1.0(完全不透明)までの値を指定します。点が重なり合う場合に内部の構造を見やすくするのに役立ちます。
  • cmap: c引数に数値の配列を渡した場合に適用するカラーマップを指定します。例えば'viridis', 'plasma', 'Blues'などがあります。

fig.colorbar()は、散布図などでc引数に数値を与え、カラーマップで色分けした場合に、色の凡例(カラーバー)を追加します。

棒グラフ (Bar Chart)

棒グラフは、カテゴリ別の数量や頻度を比較するのに適しています。

ax.bar()の使い方

縦方向の棒グラフはax.bar()メソッドを使って作成します。

“`python

カテゴリと値を準備

categories = [‘A’, ‘B’, ‘C’, ‘D’, ‘E’]
values = [25, 60, 35, 50, 40]

fig, ax = plt.subplots()

棒グラフを描画

x: 棒の位置(数値)。カテゴリ数と同じ長さの配列

height: 棒の高さ(値)

tick_label: 各棒の下に表示するラベル

ax.bar(categories, values) # ax.barは位置と高さを取る。カテゴリ名を直接渡すこともできる。

ax.set_ylabel(‘値’)
ax.set_title(‘シンプルな棒グラフ’)

plt.show()
“`

ax.bar()にカテゴリ名(文字列のリスト)と対応する値(数値のリスト)を渡すことで、自動的に適切な位置に棒を描画し、カテゴリ名をX軸のラベルとして設定してくれます。

横方向の棒グラフ (ax.barh())

横方向の棒グラフはax.barh()メソッドを使います。引数の順序が縦棒グラフと逆になり、width(棒の長さ)を指定します。

“`python

カテゴリと値を準備(同じデータを使用)

categories = [‘A’, ‘B’, ‘C’, ‘D’, ‘E’]
values = [25, 60, 35, 50, 40]

fig, ax = plt.subplots()

横方向の棒グラフを描画

y: 棒の位置(数値)

width: 棒の長さ(値)

tick_label: 各棒の左に表示するラベル

ax.barh(categories, values) # barhは位置と長さを取る。カテゴリ名を直接渡すこともできる。

ax.set_xlabel(‘値’)
ax.set_title(‘シンプルな横方向棒グラフ’)

plt.show()
“`

横方向棒グラフは、カテゴリ名が長い場合に特に有効です。

棒グラフのカスタマイズ

棒グラフも色、幅、配置などをカスタマイズできます。

“`python
categories = [‘A’, ‘B’, ‘C’, ‘D’, ‘E’]
values = [25, 60, 35, 50, 40]
colors = [‘red’, ‘blue’, ‘green’, ‘orange’, ‘purple’] # 各棒の色を指定

fig, ax = plt.subplots()

棒グラフを描画

color: 各棒の色を指定

width: 棒の幅を指定 (0.0から1.0の間で、通常0.8程度)

align: 棒とX軸の目盛りの位置関係 (‘center’または’edge’)

ax.bar(categories, values, color=colors, width=0.7, align=’center’)

ax.set_ylabel(‘値’)
ax.set_title(‘カスタマイズされた棒グラフ’)

plt.show()
“`

複数のデータ系列を持つ棒グラフ(積み上げ棒グラフや並列棒グラフ)を作成することも可能ですが、ここでは入門として基本的な棒グラフに留めます。

グラフのカスタマイズ

Matplotlibの強力な点の1つは、グラフのあらゆる要素を細かくカスタマイズできることです。ここでは、グラフの見た目をより分かりやすく、魅力的にするための主要なカスタマイズ方法を学びます。

カスタマイズは主にAxesオブジェクトの様々なメソッドを使って行います。

軸の設定

グラフの軸(X軸、Y軸)は、データの範囲や目盛り、表示方法を調整することで、読み取りやすさに大きな影響を与えます。

軸の範囲 (xlim, ylim)

表示するデータの範囲を限定したり、特定の範囲を拡大して見せたりしたい場合に、軸の範囲を設定します。

“`python
x = np.linspace(0, 10, 100)
y = np.sin(x)

fig, ax = plt.subplots()

ax.plot(x, y)

X軸の範囲を3から7に設定

ax.set_xlim(3, 7)

Y軸の範囲を-0.5から0.5に設定

ax.set_ylim(-0.5, 0.5)

ax.set_title(‘範囲を限定したサインカーブ’)

plt.show()
“`

ax.set_xlim(min_val, max_val)およびax.set_ylim(min_val, max_val)で、それぞれの軸の表示範囲を設定できます。どちらか一方の値を省略してax.set_xlim(min=3)のように記述することも可能です。

軸のラベル (xlabel, ylabel)

これは前のセクションでも触れましたが、軸に適切な単位や内容を示すラベルを付けることは必須です。

python
ax.set_xlabel('時間 (秒)')
ax.set_ylabel('振幅 (単位)')

目盛りの設定 (ticks, tick labels)

軸に表示される目盛りの位置や、それに付随するラベルを細かく制御できます。

“`python
x = np.linspace(0, 2*np.pi, 8) # 0から2πまでを7分割した8点
y = np.sin(x)

fig, ax = plt.subplots()

ax.plot(x, y)

X軸の目盛りの位置を指定

0, π/2, π, 3π/2, 2π の位置に目盛りを置きたい

tick_positions = [0, np.pi/2, np.pi, 3np.pi/2, 2np.pi]
ax.set_xticks(tick_positions)

X軸の目盛りのラベルを指定

目盛りの位置に対応するラベル(文字列)を指定

tick_labels = [‘0’, ‘π/2’, ‘π’, ‘3π/2’, ‘2π’]
ax.set_xticklabels(tick_labels)

ax.set_title(‘カスタム目盛りのサインカーブ’)

plt.show()
“`

  • ax.set_xticks(positions)およびax.set_yticks(positions):目盛りを表示したい数値のリストを指定します。
  • ax.set_xticklabels(labels)およびax.set_yticklabels(labels):それぞれの目盛りに対応して表示したい文字列のリストを指定します。

目盛りのラベルを回転させることもよくあります。特に棒グラフなどでカテゴリ名が長い場合に便利です。

“`python

例えば棒グラフの例で

ax.set_xticklabels(categories, rotation=45, ha=’right’) # haはhorizontal alignment(水平方向の配置)
“`

rotation引数で回転角度(度)を指定します。

対数軸 (xscale, yscale)

データの分布が大きく偏っている場合(例えば、値が1から1,000,000まで広がるような場合)、通常の線形スケールでは小さな値の変化が見えにくくなります。このような場合に、対数スケールを使うと便利です。

“`python

指数関数的に増加するデータ

x = np.linspace(0, 5, 100)
y = np.exp(x) # y = e^x

fig, ax = plt.subplots(1, 2, figsize=(10, 4)) # 2つのサブプロットを作成

線形スケールのY軸

ax[0].plot(x, y)
ax[0].set_title(‘線形スケール’)
ax[0].set_xlabel(‘X’)
ax[0].set_ylabel(‘exp(X)’)

対数スケールのY軸

ax[1].plot(x, y)
ax[1].set_yscale(‘log’) # Y軸を対数スケールに設定
ax[1].set_title(‘対数スケール (Y軸)’)
ax[1].set_xlabel(‘X’)
ax[1].set_ylabel(‘exp(X)’)

plt.tight_layout() # グラフ間のスペースを自動調整
plt.show()
“`

ax.set_xscale('log')またはax.set_yscale('log')で、それぞれの軸を対数スケールに設定できます。対数スケールにすると、元のデータが指数関数的に増加していても、直線的な関係に見えるようになります。

タイトルと凡例

グラフのタイトルと凡例は、グラフ全体の内容や、複数のデータ系列が何を示しているかを伝える上で不可欠です。

タイトルの設定 (title)

Axesオブジェクトにタイトルを設定します。

python
ax.set_title('これが私の素晴らしいグラフです', fontsize=16, color='darkblue')

ax.set_title()には、フォントサイズ(fontsize)や色(color)などの引数を指定して、タイトルの見た目をカスタマイズできます。Figure全体のタイトルを設定したい場合は、fig.suptitle('Figure全体のタイトル', fontsize=18)を使います。

凡例の設定 (legend)

複数のデータ系列をプロットした場合、それぞれの線や点が何を示しているかを区別するために凡例(レジェンド)が必要です。凡例を表示するには、プロット時にlabel引数で各系列の名前を指定し、その後にax.legend()を呼び出します。

“`python
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()

label引数で凡例の名前を指定

ax.plot(x, y1, label=’sin(x)’)
ax.plot(x, y2, label=’cos(x)’)

ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
ax.set_title(‘サインとコサイン’)

凡例を表示

ax.legend()

plt.show()
“`

ax.legend()には、凡例の配置やスタイルに関する様々なオプションがあります。

“`python

凡例を右上 (upper right) に配置

ax.legend(loc=’upper right’)

凡例をグラフの外に配置 (例えばFigureの下中央)

bbox_to_anchor は凡例ボックスを配置する基準点を指定。

loc はその基準点に対する凡例ボックスのどの部分を配置するかを指定。

ncol は凡例の列数を指定。

ax.legend(bbox_to_anchor=(0.5, -0.2), loc=’upper center’, ncol=2)

凡例に影をつける

ax.legend(shadow=True)

凡例に枠線をつける/消す

ax.legend(frameon=False) # 枠線なし
ax.legend(frameon=True) # 枠線あり (デフォルト)

凡例のタイトルを設定

ax.legend(title=’関数’)
“`

loc引数には、'upper left', 'upper right', 'lower left', 'lower right', 'center', 'best' (最適な位置を自動選択) などを指定できます。bbox_to_anchorを使うと、より細かく凡例の位置を制御できます。タプル(x, y)でFigureやAxesに対する相対座標を指定します。

線のスタイルとマーカー

折れ線グラフや散布図の見た目を調整することで、複数の系列を区別したり、データの特性を強調したりできます。

線の太さ (linewidth)

線の太さを指定するには、linewidth引数を使います(省略形はlw)。

python
fig, ax = plt.subplots()
ax.plot(x, y1, label='sin(x)', linewidth=2)
ax.plot(x, y2, label='cos(x)', lw=1) # lwでもOK
ax.legend()
plt.show()

線のスタイル (linestyle)

線の種類を指定するには、linestyle引数を使います(省略形はls)。

python
fig, ax = plt.subplots()
ax.plot(x, y1, label='sin(x)', ls='-') # 実線 (デフォルト)
ax.plot(x, y2, label='cos(x)', ls='--') # 破線
ax.plot(x, y1*0.5, label='0.5sin(x)', ls='-.') # 一点鎖線
ax.plot(x, y2*0.5, label='0.5cos(x)', ls=':') # 点線
ax.legend()
plt.show()

省略形の文字列コードもよく使われます: - (実線), -- (破線), -. (一点鎖線), : (点線)。

マーカーの種類 (marker)

折れ線グラフでも、各データポイントの位置にマーカーを表示させることができます。marker引数を使います。

“`python
x_sparse = np.linspace(0, 10, 10) # 少なめのデータ点
y_sparse = np.sin(x_sparse)

fig, ax = plt.subplots()
ax.plot(x_sparse, y_sparse, marker=’o’) # 各点に円形マーカーを表示
plt.show()
“`

よく使われるマーカーの種類:'o' (円), 'x' (X), '+' (プラス), '*' (アスタリスク), '.' (点), ',' (ピクセル), 's' (正方形), 'D' (ひし形), '^' (上向き三角形), 'v' (下向き三角形), '<' (左向き三角形), '>' (右向き三角形) など。

マーカーのサイズ (markersize)

マーカーのサイズはmarkersize引数で指定します(省略形はms)。

python
fig, ax = plt.subplots()
ax.plot(x_sparse, y_sparse, marker='o', markersize=8)
plt.show()

色の指定 (color)

線やマーカーの色を指定するには、color引数を使います(省略形はc)。様々な形式で色を指定できます。

python
fig, ax = plt.subplots()
ax.plot(x, y1, color='red', label='sin(x)') # 色の名前 (例: 'red', 'blue', 'green', 'black', 'white', 'gray'...)
ax.plot(x, y2, color='#0077cc', label='cos(x)') # HEXカラーコード
ax.plot(x, y1*0.5, color=(0.1, 0.5, 0.2), label='0.5sin(x)') # RGBタプル (0.0から1.0の浮動小数点数)
ax.plot(x, y2*0.5, color='C4', label='0.5cos(x)') # デフォルトのカラーサイクルからの指定 (C0, C1, ...)
ax.legend()
plt.show()

color引数には、上記以外にも多数の色の指定方法があります。特にRGBタプルを使うと、任意の色を細かく指定できます。'C0', 'C1'のような指定は、Matplotlibがデフォルトで用意している色のサイクルから順番に色を選ぶ方法です。

テキストと注釈

グラフ上の特定の場所にテキストを追加したり、データポイントに矢印付きの注釈を付けたりすることで、重要な情報や傾向を強調できます。

テキストの追加 (ax.text())

グラフ内の任意の座標にテキストを配置します。

“`python
x = np.linspace(0, 10, 100)
y = np.sin(x)

fig, ax = plt.subplots()
ax.plot(x, y)

グラフ内の特定の位置にテキストを追加

x, y: テキストを配置する座標

s: 表示する文字列

ax.text(5, 0.5, ‘ピーク付近’, fontsize=12, color=’red’)
ax.text(8, -0.8, ‘ボトム付近’, fontsize=12, color=’blue’, horizontalalignment=’center’) # 配置を指定

ax.set_xlabel(‘X’)
ax.set_ylabel(‘sin(x)’)
ax.set_title(‘テキストを追加したグラフ’)

plt.show()
“`

ax.text(x, y, s)メソッドで、座標(x, y)に文字列sを表示します。fontsize, color, horizontalalignment (ha), verticalalignment (va) などの引数でテキストのスタイルや配置を調整できます。座標系は、デフォルトではデータ座標系です。

注釈の追加 (ax.annotate())

特定のデータポイントやグラフ上の特徴的な位置に矢印とテキストで注釈を付けます。

“`python
x = np.linspace(0, 10, 100)
y = np.sin(x)

fig, ax = plt.subplots()
ax.plot(x, y)

注釈を追加

text: 注釈として表示する文字列

xy: 注釈を付けたい対象の座標 (data coordinates)

xytext: 注釈テキストを配置する座標 (通常はoffset points)

arrowprops: 矢印のスタイルを指定する辞書

ax.annotate(‘最初のピーク’, xy=(np.pi/2, 1.0), xytext=(5, 1.5),
arrowprops=dict(facecolor=’black’, shrink=0.05), # shrinkは矢印の先端と根元からどれだけ離すか
fontsize=12)

ax.set_xlabel(‘X’)
ax.set_ylabel(‘sin(x)’)
ax.set_title(‘注釈を追加したグラフ’)
ax.set_ylim(-1.2, 2.0) # 注釈が表示されるようにY軸範囲を調整

plt.show()
“`

ax.annotate(text, xy, xytext, arrowprops)は強力なメソッドです。
* text: 表示する注釈文字列。
* xy: 注釈の対象となるポイントの座標です。デフォルトはデータ座標系。
* xytext: 注釈テキストの座標です。デフォルトはoffset points (ピクセル単位?) ですが、textcoords引数で座標系を指定できます(例: 'data', 'offset points', 'axes fraction', 'figure fraction')。
* arrowprops: 矢印のスタイルを辞書形式で指定します。facecolor, edgecolor, linewidth, linestyle, shrink, width (矢印の幅), headwidth (矢印の頭の幅), headlength (矢印の頭の長さ) など、様々なオプションがあります。

複数のグラフを配置する

一つのFigure内に複数のグラフ(Axes)を配置することで、異なる視点からのデータを比較したり、関連する情報をまとめて表示したりできます。

同じAxesに複数のプロット

これはすでに折れ線グラフのセクションで見た方法です。同じAxesオブジェクトに対して複数のplot()scatter()などのメソッドを呼び出すことで、同じ座標系上に複数のデータ系列を描画できます。

python
fig, ax = plt.subplots()
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
ax.legend()
plt.show()

複数のAxesを持つFigure (plt.subplots())

Figure内に複数のAxesを作成する最も簡単で一般的な方法は、plt.subplots()関数にnrows(行数)とncols(列数)を指定することです。

“`python

2行1列のサブプロットを作成

fig, axes = plt.subplots(nrows=2, ncols=1)

axesはAxesオブジェクトのNumPy配列

最初のAxesは axes[0]

二番目のAxesは axes[1]

x = np.linspace(0, 10, 100)

最初のAxesにサインカーブを描画

axes[0].plot(x, np.sin(x))
axes[0].set_title(‘上のグラフ: sin(x)’)
axes[0].set_ylabel(‘Y’)

二番目のAxesにコサインカーブを描画

axes[1].plot(x, np.cos(x), color=’orange’)
axes[1].set_title(‘下のグラフ: cos(x)’)
axes[1].set_xlabel(‘X’)
axes[1].set_ylabel(‘Y’)

plt.tight_layout() # サブプロット間のスペースを自動調整して重なりを防ぐ
plt.show()
“`

plt.subplots(nrows, ncols)は、Figureオブジェクトと、AxesオブジェクトのNumPy配列を返します。配列のインデックスを使って、それぞれのAxesにアクセスし、個別にプロットや設定を行います。

例えば、2×2のサブプロットを作成した場合は、axesは2×2の配列となり、各Axesにはaxes[0, 0], axes[0, 1], axes[1, 0], axes[1, 1]のようにアクセスします。

plt.tight_layout()関数は、サブプロット、タイトル、ラベルなどが互いに重ならないように、サブプロット間のスペースを自動的に調整してくれる便利な関数です。

add_subplot()を使った手動でのAxes追加

plt.subplots()を使うのが一般的ですが、より細かくAxesの配置を制御したい場合や、既存のFigureにAxesを追加したい場合は、Figureオブジェクトのadd_subplot()メソッドを使うことができます。

fig.add_subplot(nrows, ncols, index)のように指定します。これは、nrows x ncolsのグリッドを考えたときに、index番目の位置にAxesを追加するという意味です。インデックスは1から始まります。

“`python

新しいFigureを作成

fig = plt.figure()

2行2列のグリッドの1番目の位置にAxesを追加

ax1 = fig.add_subplot(2, 2, 1)
ax1.plot(np.random.rand(10))
ax1.set_title(‘Subplot 1’)

2行2列のグリッドの4番目の位置にAxesを追加

ax2 = fig.add_subplot(2, 2, 4)
ax2.scatter(np.random.rand(10), np.random.rand(10))
ax2.set_title(‘Subplot 4’)

add_subplotはplt.subplot(nrows, ncols, index)としても使用可能 (pyplot API)

ax3 = plt.subplot(2, 2, 2) # これはplt.figure()を作成し、そこにAxesを追加する

ax3.hist(np.random.randn(100))

ax3.set_title(‘Subplot 2’)

plt.tight_layout() # add_subplotを使った場合でも有効
plt.show()
“`

add_subplot()は、plt.subplots()よりも手動での制御が必要ですが、複雑なレイアウトを構築する際には有用な場合があります。

GridSpecを使った複雑なレイアウト

plt.subplots()add_subplot()では、グリッド状に等間隔でAxesを配置するのが基本です。しかし、特定のAxesが複数の「セル」を占めるような、より複雑なレイアウトを作成したい場合は、matplotlib.gridspec.GridSpecを使うと便利です。

GridSpecは、Figure内の全体的なグリッド構造を定義し、そのグリッド内の特定の位置や範囲を指定してAxesを作成することができます。

“`python
import matplotlib.gridspec as gridspec

fig = plt.figure(figsize=(10, 5)) # Figureサイズを指定

2行3列のグリッド構造を定義

gs = gridspec.GridSpec(2, 3, figure=fig)

最初のAxes: 1行目全体 (0行目の0列目から2列目まで)

ax1 = fig.add_subplot(gs[0, :])
ax1.plot(np.linspace(0, 10, 100), np.sin(np.linspace(0, 10, 100)))
ax1.set_title(‘Main Plot (spanning 3 columns)’)

二番目のAxes: 2行目の最初の1列 (1行目の0列目)

ax2 = fig.add_subplot(gs[1, 0])
ax2.hist(np.random.randn(100), bins=10)
ax2.set_title(‘Subplot 1 (1st column)’)

三番目のAxes: 2行目の残りの2列 (1行目の1列目から2列目まで)

ax3 = fig.add_subplot(gs[1, 1:])
ax3.scatter(np.random.rand(50), np.random.rand(50))
ax3.set_title(‘Subplot 2 (spanning 2 columns)’)

plt.tight_layout()
plt.show()
“`

GridSpec(nrows, ncols, figure=fig)でグリッドの行数と列数を定義し、どのFigureに紐づけるかを指定します。Axesを追加する際に、gs[row_index, col_index]のようにスライスを使って、Axesが占めるグリッドの範囲を指定します。スライスを使うことで、複数のセルを結合したようなAxesを作成できます。

GridSpecを使うことで、より柔軟かつ複雑なグラフ配置が可能になります。

様々なグラフの種類

Matplotlibは、折れ線グラフ、散布図、棒グラフ以外にも、様々な種類のグラフ作成機能を提供しています。ここでは、データ分析でよく使われるいくつかのグラフタイプを紹介します。

ヒストグラム (Histogram)

ヒストグラムは、数値データの分布を把握するのに役立ちます。データをいくつかの区間(ビン)に分割し、各区間に含まれるデータの個数(度数)を棒グラフで表示します。

“`python

標準正規分布に従う乱数データ

data = np.random.randn(1000)

fig, ax = plt.subplots()

ヒストグラムを描画

x: 度数を計算したいデータ

bins: ビンの数またはビンの境界を指定

density: Trueにすると、度数ではなく確率密度を表示 (合計面積が1になる)

ax.hist(data, bins=30, density=False, alpha=0.7, color=’skyblue’, edgecolor=’black’)

ax.set_xlabel(‘値’)
ax.set_ylabel(‘度数’)
ax.set_title(‘ヒストグラム’)

plt.show()
“`

ax.hist(x)メソッドは、xのデータのヒストグラムを描画します。
* bins: ビンの数を整数で指定するか、ビンの境界値を配列で指定します。ビンの数を適切に選ぶことは、分布を正確に把握する上で重要です。
* density=True: Y軸を度数ではなく確率密度に正規化します。これにより、異なるサンプルサイズのデータセットの分布を比較しやすくなります。
* alpha: 棒の透明度を設定します。複数のヒストグラムを重ねて表示する場合に便利です。
* edgecolor: 棒の境界線の色を指定します。

箱ひげ図 (Box Plot)

箱ひげ図(ボックスプロット)は、データの分布の要約統計量(中央値、四分位数、外れ値など)を視覚的に示すのに適しています。複数のグループ間の分布を比較する際によく使われます。

“`python

複数のグループのサンプルデータ

data1 = np.random.normal(0, 1, 100) # 平均0, 標準偏差1
data2 = np.random.normal(2, 1.5, 100) # 平均2, 標準偏差1.5
data3 = np.random.normal(-1, 0.5, 100) # 平均-1, 標準偏差0.5

data = [data1, data2, data3] # 複数のデータセットをリストで渡す

fig, ax = plt.subplots()

箱ひげ図を描画

x: 箱ひげ図を描画したいデータセットのリスト

ax.boxplot(data, patch_artist=True, medianprops=dict(color=’red’)) # patch_artist=Trueで箱を塗りつぶす

X軸のラベルを設定(各箱に対応)

ax.set_xticklabels([‘Group 1’, ‘Group 2’, ‘Group 3’])
ax.set_ylabel(‘値’)
ax.set_title(‘グループ別箱ひげ図’)

plt.show()
“`

ax.boxplot(x)メソッドは、データのリスト(またはNumPy配列)を受け取り、各要素に対して箱ひげ図を描画します。
* 箱は、データの第1四分位数(Q1)から第3四分位数(Q3)までの範囲を示します。箱の中央の線は中央値(メディアン)です。
* ひげは、通常、Q1 – 1.5 * IQR から Q3 + 1.5 * IQR (IQRは四分位範囲 Q3-Q1) の範囲内のデータの最小値と最大値まで伸びます。
* ひげの外側の点は外れ値(アウトライヤー)として個別に表示されます。
* patch_artist=True: 箱を塗りつぶします。デフォルトは枠線のみです。
* medianprops: 中央値を示す線のスタイルを辞書で指定します。

円グラフ (Pie Chart)

円グラフは、全体に占める各カテゴリの割合を示すのに適しています。ただし、カテゴリ数が多い場合や、割合の差が小さい場合には、情報を正確に読み取るのが難しくなるため、使用には注意が必要です。

“`python

カテゴリ別のデータ(割合や合計)

labels = [‘Apple’, ‘Banana’, ‘Cherry’, ‘Date’]
sizes = [15, 30, 45, 10] # 各カテゴリの割合(合計が100でなくても良い、Matplotlibが正規化してくれる)
colors = [‘gold’, ‘yellowgreen’, ‘lightcoral’, ‘lightskyblue’]
explode = (0, 0.1, 0, 0) # 2番目のスライス(Banana)を少し分離させる

fig, ax = plt.subplots()

円グラフを描画

x: 各スライスのサイズ

explode: 各スライスを分離させる距離

labels: 各スライスのラベル

colors: 各スライスの色

autopct: 各スライスに割合(パーセンテージ)を表示するための文字列フォーマット

shadow: 影をつけるかどうか

startangle: 最初のスライスの開始角度(デフォルトは0、Y軸正方向から時計回りが一般的な円グラフだが、MatplotlibはX軸正方向から反時計回り)

ax.pie(sizes, explode=explode, labels=labels, colors=colors,
autopct=’%1.1f%%’, shadow=True, startangle=140) # %1.1f%% は小数点以下1桁のパーセント表示

円を真円に保つ

ax.axis(‘equal’) # Equal aspect ratio ensures that pie is drawn as a circle.

ax.set_title(‘果物の割合’)

plt.show()
“`

ax.pie(x)メソッドは、割合を示す数値のリストまたは配列を受け取ります。
* autopct: %1.1f%%のように指定すると、各スライスに計算された割合がテキストとして表示されます。%1.1fは小数点以下1桁の浮動小数点数を意味し、%%はリテラルの%記号を表示します。
* startangle: 最初のスライスがどこから始まるかを角度(度)で指定します。90とするとY軸正方向から始まります。
* ax.axis('equal'): これを呼び出さないと、Axesの縦横比がデータに合わせて調整され、円が楕円になる可能性があります。真円に保つために重要です。

等高線図 (Contour Plot)

等高線図は、3番目の変数(通常はZ値)の分布を、2次元平面上の等しいZ値を持つ点を結んだ線(等高線)で表現するグラフです。地形図の等高線や、気圧配置図の等圧線のようなものです。

等高線図を作成するには、X, Y座標に対応するZ値のグリッドデータが必要です。通常、NumPyのmeshgrid関数を使って、XとYの配列からグリッド座標を生成します。

“`python

グリッドデータの生成

x = np.linspace(-5, 5, 50)
y = np.linspace(-5, 5, 40)
X, Y = np.meshgrid(x, y) # グリッド座標行列を作成

Z値の計算 (例: 二変数関数)

Z = np.sin(np.sqrt(X2 + Y2))

fig, ax = plt.subplots()

等高線を描画

X, Y: グリッド座標行列

Z: 各グリッド点でのZ値

levels: 表示する等高線のZ値のレベルを指定 (省略すると自動計算)

colors: 等高線の色を指定 (単一の色名、またはレベル数と同じ色のリスト)

ax.contour(X, Y, Z, levels=10, colors=’black’) # 10本の等高線を黒で表示

等高線を塗りつぶしで表示 (カラーマップを使用)

cmap: 使用するカラーマップ

alpha: 透明度

extend: Z値の範囲外をどう扱うか (‘neither’, ‘both’, ‘min’, ‘max’)

contourf = ax.contourf(X, Y, Z, levels=20, cmap=’viridis’, alpha=0.8) # 20段階の色分けで塗りつぶし

カラーバーを追加

fig.colorbar(contourf, ax=ax, label=’Z値’)

ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
ax.set_title(‘等高線図’)

plt.show()
“`

  • ax.contour(X, Y, Z): 等高線(線)を描画します。
  • ax.contourf(X, Y, Z): 等高線間の領域を塗りつぶして表示します。
  • levels: 描画する等高線のZ値を指定します。整数を指定するとその数の等高線が自動的に計算されます。値のリストを指定すると、その値に対応する等高線が描画されます。
  • cmap: 塗りつぶしの際に使用するカラーマップを指定します。

ヒートマップ (Heatmap)

ヒートマップは、行列形式のデータを色の濃淡で表現するグラフです。相関行列や、カテゴリ間の関係性を示すのに適しています。ax.imshow()ax.matshow()関数を使って作成できます。

“`python

ランダムな行列データ

data = np.random.rand(10, 10) # 10×10の行列

fig, ax = plt.subplots()

ヒートマップを描画

X: 表示する行列データ

cmap: 使用するカラーマップ

interpolation: ピクセルの補間方法 (None, ‘nearest’, ‘bilinear’など)

im = ax.imshow(data, cmap=’hot’, interpolation=’nearest’)

カラーバーを追加

fig.colorbar(im, ax=ax, label=’値’)

軸の目盛りの設定 (任意)

ax.set_xticks(np.arange(data.shape[1]))
ax.set_yticks(np.arange(data.shape[0]))
ax.set_xticklabels(np.arange(data.shape[1]))
ax.set_yticklabels(np.arange(data.shape[0]))

ax.set_xlabel(‘列インデックス’)
ax.set_ylabel(‘行インデックス’)
ax.set_title(‘ヒートマップ’)

plt.show()
“`

  • ax.imshow(X): 行列Xを画像として表示します。各要素の値がカラーマップによって色に変換されます。
  • cmap: 使用するカラーマップを指定します。'hot', 'viridis', 'plasma', 'Blues'など、様々なカラーマップがあります。
  • interpolation: ピクセルの表示方法を指定します。データが連続的である場合は'bilinear'などが滑らかに見えますが、離散的な値を正確に見たい場合は'nearest'が適しています。

より高度なヒートマップ(例えばSeabornライブラリのseaborn.heatmap)では、セルの中に値そのものを表示したり、行や列にクラスタリングの結果を表示したりする機能も提供されています。

3Dプロット (mplot3d)

Matplotlibは、3次元データの可視化もサポートしています。3Dプロットを作成するには、mpl_toolkits.mplot3dモジュールをインポートし、Axesを作成する際にprojection='3d'を指定する必要があります。

“`python

3D Axesを作成

fig = plt.figure()
ax = fig.add_subplot(111, projection=’3d’) # または fig, ax = plt.subplots(subplot_kw={‘projection’: ‘3d’})

3D散布図

サンプルデータ

x = np.random.rand(100)
y = np.random.rand(100)
z = np.random.rand(100)
ax.scatter(x, y, z)

3D折れ線グラフ (例: ヘリックス)

theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
z = np.linspace(-2, 2, 100)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
ax.plot(x, y, z, label=’螺旋’)
ax.legend()

軸ラベルを設定

ax.set_xlabel(‘X軸’)
ax.set_ylabel(‘Y軸’)
ax.set_zlabel(‘Z軸’)
ax.set_title(‘3Dプロット’)

plt.show()
“`

3D Axesオブジェクト (ax) が作成できたら、通常のAxesと同様にメソッドを呼び出してプロットします。ただし、メソッド名が少し異なる場合があります(例: scatterは同じ、plotも同じ)。

3D表面図 (plot_surface)

3Dプロットでよく使われるのが表面図です。X, Yグリッド上の各点に対応するZ値を滑らかな表面として表示します。等高線図と同様に、X, Y, Zのグリッドデータが必要です。

“`python
from mpl_toolkits.mplot3d import Axes3D

グリッドデータの生成

x = np.linspace(-5, 5, 50)
y = np.linspace(-5, 5, 50)
X, Y = np.meshgrid(x, y)

Z値の計算 (例: 二変数関数)

Z = np.sin(np.sqrt(X2 + Y2)) # これは等高線図と同じ関数

fig = plt.figure()
ax = fig.add_subplot(111, projection=’3d’)

3D表面図を描画

X, Y, Z: グリッドデータ

cmap: 使用するカラーマップ

rstride, cstride: 行列方向のステップ数を指定(表示を粗くして高速化)

surface = ax.plot_surface(X, Y, Z, cmap=’viridis’, rstride=1, cstride=1, alpha=0.9)

カラーバーを追加

fig.colorbar(surface, ax=ax, shrink=0.5, aspect=5)

ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
ax.set_zlabel(‘Z’)
ax.set_title(‘3D表面図’)

plt.show()
“`

ax.plot_surface(X, Y, Z)は、グリッドデータから表面図を作成します。rstridecstrideは、描画するグリッドのステップ数を指定します。大きな値を指定すると、メッシュが粗くなりますが、描画が速くなります。

3Dプロットは視覚的に魅力的ですが、データの関係性を正確に読み取るのが難しい場合もあるため、目的に応じて適切に使用することが重要です。

カラーマップ (Colormaps)

カラーマップは、数値データを色にマッピングするための仕組みです。等高線図、ヒートマップ、散布図などで、数値の大小を色の濃淡や種類で表現するのに使われます。Matplotlibは様々な組み込みカラーマップを提供しており、目的に応じて適切なカラーマップを選択することが重要です。

カラーマップの選択と適用

カラーマップは、連続的なデータの変化を示すためのもの(連続カラーマップ)と、離散的なカテゴリを示すためのもの(離散カラーマップ)に大別されます。また、特定の値の大きさを強調するためのもの、発散する値(例えば0からの正負両方向への変化)を示すためのものなど、様々な種類があります。

よく使われる連続カラーマップの例:
* 知覚的に均一なシーケンシャル: viridis, plasma, inferno, magma, cividis (色の変化が滑らかで、色の明るさの変化も単調なため、人間の知覚と相関しやすい)
* シーケンシャル: Blues, Greens, Reds, coolwarm (単一の色が濃くなっていく、または二色間の変化)
* 発散: coolwarm, bwr (中央値付近で特定の色になり、そこから両方向に離れるにつれて別の色に変化する)

カラーマップは、プロット関数のcmap引数に文字列名で指定します。

“`python

例: 散布図でz値を色の濃淡で表現

x = np.random.rand(100) * 10
y = np.random.rand(100) * 10
z = x * y # z値を計算

fig, ax = plt.subplots()

z値をカラーマップで色分けして表示

scatter = ax.scatter(x, y, c=z, cmap=’viridis’)

カラーバーを追加

fig.colorbar(scatter, ax=ax, label=’X * Y の値’)

ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
ax.set_title(‘カラーマップを使った散布図’)

plt.show()
“`

カラーマップの選び方に関するヒント:
* データの種類: データの種類(連続値、カテゴリ、発散値など)に応じて適切なタイプのカラーマップを選びましょう。
* アクセシビリティ: 色覚多様性を持つ人々にも分かりやすいカラーマップ(例: viridis, plasma, cividis)を選択することを検討しましょう。グレースケール印刷でも情報が失われにくいかどうかも考慮点です。
* 伝えるメッセージ: どのような情報を強調したいかに応じてカラーマップを選びましょう。例えば、高い値を強調したい場合は、明るい色や彩度の高い色が最後の値に対応するカラーマップを選ぶ、などです。

Matplotlibの公式ドキュメントには、様々なカラーマップが紹介されており、それぞれの特徴を比較できます。

カラーバー (colorbar) の追加

カラーマップを使って色の濃淡で数値を示した場合、その色が具体的にどの数値に対応するのかを示すためにカラーバーが必要です。

カラーバーは、プロットオブジェクト(ax.scatter, ax.contourf, ax.imshow, ax.plot_surfaceなどの戻り値)を指定して、FigureオブジェクトまたはAxesオブジェクトのcolorbar()メソッドを使って追加します。一般的にはfig.colorbar()を使用し、どのAxesに関連付けるかをax引数で指定します。

“`python

… 上記のカラーマップを使った散布図のコード …

fig.colorbar(プロットオブジェクト, ax=関連付けるAxes, label=’カラーバーのラベル’)

fig.colorbar(scatter, ax=ax, label=’X * Y の値’)

… plt.show() …

“`

fig.colorbar()には、カラーバーのサイズ、位置、ラベルなどの様々なカスタマイズオプションがあります。shrink引数でサイズを縮小したり、aspectで縦横比を調整したりできます。

テキスト、フォント、数式

グラフのタイトル、軸ラベル、注釈などのテキストは、情報伝達の重要な要素です。フォントの種類、サイズ、スタイルを調整することで、グラフ全体の視覚的な印象を向上させ、読みやすさを高めることができます。また、科学技術分野のグラフでは数式を表示する必要がある場合もあります。

フォントの設定

Matplotlibのテキスト要素のフォントは、様々な方法で設定できます。

特定のテキスト要素(タイトル、ラベル、凡例など)を作成する際に、fontsize, fontweight, fontstyle, fontfamilyなどの引数を指定できます。

“`python
fig, ax = plt.subplots()
ax.plot([0, 1], [0, 1])

タイトルにフォント設定を適用

ax.set_title(‘太字のタイトル’, fontsize=14, fontweight=’bold’)

X軸ラベルにフォント設定を適用

ax.set_xlabel(‘X軸ラベル’, fontsize=12, fontstyle=’italic’)

Y軸ラベルに特定のフォントファミリーを適用 (システムにインストールされている必要あり)

例として ‘serif’, ‘sans-serif’, ‘cursive’, ‘fantasy’, ‘monospace’ などが指定可能

ax.set_ylabel(‘Y軸ラベル’, fontsize=12, fontfamily=’serif’)

plt.show()
“`

グラフ全体のデフォルトフォントを設定するには、Matplotlibのランタイム設定(rc settings)を変更します。

“`python

グローバルなフォント設定を変更

plt.rcParams[‘font.family’] = ‘DejaVu Sans’ # または ‘Arial’, ‘Times New Roman’ など
plt.rcParams[‘font.size’] = 12
plt.rcParams[‘axes.labelsize’] = 14 # 軸ラベルのフォントサイズ
plt.rcParams[‘axes.titlesize’] = 16 # タイトルのフォントサイズ

その他の設定例:

plt.rcParams[‘font.serif’] = [‘Times New Roman’, ‘Liberation Serif’, ‘DejaVu Serif’] # serifフォントの候補リスト

plt.rcParams[‘font.sans-serif’] = [‘Arial’, ‘Liberation Sans’, ‘DejaVu Sans’] # sans-serifフォントの候補リスト

plt.rcParams[‘mathtext.fontset’] = ‘cm’ # 数式フォントの設定

設定変更後にグラフを作成

fig, ax = plt.subplots()
ax.plot([0, 1], [0, 1])
ax.set_title(‘タイトル’)
ax.set_xlabel(‘Xラベル’)
ax.set_ylabel(‘Yラベル’)

plt.show()

元の設定に戻す場合は、plt.rcParamsをリセットするか、元の値を保存しておいて復元する

例えば、plt.rcParams.update(plt.rcParamsDefault) で多くの設定をデフォルトに戻せる

“`

これらの設定は、それ以降に作成されるすべてのグラフに適用されます。日本語フォントを使用したい場合は、システムに日本語フォントがインストールされており、そのフォント名を指定する必要があります。また、日本語表示には別途設定が必要な場合もあります(特にLaTeXを使用する場合など)。

LaTeX数式の表示

Matplotlibは、テキスト中にLaTeXの構文を使って数式を表示する機能をサポートしています。これにより、高品質な数式をグラフに含めることができます。

数式として解釈させたい文字列を、生の文字列(raw string)として定義し、ドル記号$で囲みます。

“`python
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)

fig, ax = plt.subplots()

ax.plot(x, y)

タイトルに数式を含める

ax.set_title(r’$\sin(x)$ のグラフ’) # r” でraw string, $ $ で数式モード

軸ラベルに数式を含める

ax.set_xlabel(r’変数 $x$’)
ax.set_ylabel(r’$f(x) = \sin(x)$’)

グラフ内に数式をテキストとして表示

ax.text(4, 0.5, r’$ \int_0^\pi \sin(x) dx = 2 $’, fontsize=14)

plt.show()
“`

  • 文字列の前にrを付けることで、バックスラッシュ\をエスケープ文字としてではなく、文字通りに扱わせる raw string になります。これはLaTeX構文でバックスラッシュを多用する場合に便利です。
  • 数式はドル記号$で囲みます。インライン数式は$...$、ディスプレイ数式(中央揃えで独立した行に表示)は$$...$$を使います。
  • 分数 (\frac{a}{b})、上付き/下付き文字 (a^b, a_b)、ギリシャ文字 (\alpha, \beta, \gamma, \piなど)、積分 (\int), 合計 (\sum), 根号 (\sqrt{x}) など、多くの標準的なLaTeX数式コマンドが使えます。

日本語とLaTeX数式の併用:

日本語とLaTeX数式を併用する場合、特にWindows環境などでは別途設定が必要になることがあります。具体的には、LaTeXのバックエンドとしてインストールされたTeXディストリビューションを使用するようにMatplotlibを設定するか、Unicodeをサポートするフォントを設定する必要があります。これは少し高度なトピックになるため、詳細はこの記事では割愛しますが、「matplotlib 日本語数式」などで検索すると解説が見つかります。

インタラクティブ機能とアニメーション

Matplotlibは、デスクトップ環境で実行する場合、グラフの拡大・縮小、パン(移動)、保存といった基本的なインタラクティブ機能がツールバーとして提供されます。

また、時間の経過に伴うデータの変化などを視覚的に表現するために、グラフをアニメーションさせる機能も提供されています。これはmatplotlib.animationモジュールを使いますが、比較的複雑なため、ここでは基本的な概念の紹介に留めます。

“`python

インタラクティブな表示 (デスクトップ環境の場合、通常デフォルトで有効)

グラフウィンドウが表示され、ツールバーで操作可能

fig, ax = plt.subplots()
ax.plot([0, 1], [0, 1])
ax.set_title(‘インタラクティブなグラフ’)

plt.show() # これで表示されるウィンドウにツールバーが付く
“`

Jupyter Notebookなどの環境では、%matplotlib notebookのようなマジックコマンドを使うことで、ノートブック内にインタラクティブなグラフを埋め込むことができます(ただし、環境によっては動作しない場合があります)。

アニメーションの基本は、グラフの内容を少しずつ変更しながら何度も再描画することです。matplotlib.animation.FuncAnimationクラスなどが使われます。これは、更新関数(各フレームでグラフをどう描画するかを定義)とフレーム数を指定してアニメーションオブジェクトを作成し、それを表示または保存します。

“`python

アニメーションの簡単な例 (概念のみ)

from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots()

x_data = []

y_data = []

line, = ax.plot([], [], ‘r-‘) # 最初は空のlineオブジェクトを作成

def update(frame):

# frame番号に基づいてデータを更新

x_data.append(frame)

y_data.append(np.sin(frame / 10.0))

line.set_data(x_data, y_data)

ax.set_xlim(0, frame * 1.1 + 1) # x軸範囲を適宜更新

ax.set_ylim(-1.1, 1.1)

return line, # 更新されたアーティストのタプルを返す

ani = FuncAnimation(fig, update, frames=range(100), blit=True) # blit=Trueで変更された部分だけ描画

ani.save(‘sine_animation.gif’, writer=’imagemagick’) # gifとして保存するにはImageMagickが必要

plt.show()

“`

アニメーションはデータの時間的な変化やシミュレーション結果などを視覚的に理解するのに非常に強力ですが、設定がやや複雑であり、外部ライブラリ(ImageMagickなど)への依存がある場合もあります。

より高度なトピック (簡単な紹介)

Matplotlibには、ここで紹介した基本機能以外にも、多くの高度な機能があります。いくつか簡単に紹介します。

スタイルの適用 (plt.style.use())

Matplotlibには、あらかじめ定義されたグラフのスタイル(色、線の太さ、フォントサイズなど)のセットが用意されています。これらを適用することで、簡単にグラフの見た目を変更できます。

“`python

利用可能なスタイルを確認

print(plt.style.available)

‘ggplot’ スタイルを適用

plt.style.use(‘ggplot’)

スタイル適用後にグラフを作成

x = np.linspace(0, 10, 100)
fig, ax = plt.subplots()
ax.plot(x, np.sin(x), label=’sin(x)’)
ax.plot(x, np.cos(x), label=’cos(x)’)
ax.legend()
ax.set_title(‘ggplot スタイル’)
plt.show()

他のスタイル例: ‘seaborn-v0_8’, ‘fivethirtyeight’, ‘dark_background’ など

スタイルを解除する場合は、plt.style.use(‘default’)

“`

plt.style.use(style_name)でスタイルを適用できます。複数のスタイルをリストで渡して重ねて適用することも可能です。

カスタマイズ可能なバックエンド

Matplotlibは、様々な出力形式(GUIウィンドウ、画像ファイル、Webバックエンドなど)に対応しており、これらを「バックエンド」と呼びます。どのバックエンドを使用するかは、グラフの表示方法や保存方法に影響します。通常、ユーザーが意識する必要はありませんが、特定の環境や要件(例えば、GUIなしのサーバーで画像ファイルを生成する場合)では、バックエンドを明示的に指定することがあります。

例えば、GUIを表示せずに画像ファイルを生成したい場合は、スクリプトの最初にGUIバックエンド以外のバックエンドを指定します(ただし、matplotlib.use()は他のmatplotlib関連のインポートや呼び出しよりも前に実行する必要があります)。

“`python

import matplotlib

matplotlib.use(‘Agg’) # GUIを使用しないバックエンド (ファイルの生成のみ)

import matplotlib.pyplot as plt

# … グラフ作成コード …

plt.savefig(‘my_plot.png’)

“`

'Agg'は、画像ファイルを生成するための一般的なバックエンドです。これにより、サーバー環境などGUIが表示できない場所でもMatplotlibを使うことができます。

実践的なヒントとベストプラクティス

Matplotlibの機能を学ぶだけでなく、実際のデータ可視化プロジェクトで役立つ実践的なヒントとベストプラクティスを知っておくことは重要です。

コードの構造化 (関数化)

複数のグラフを作成する場合や、同じ種類のグラフを繰り返し作成する場合は、グラフ作成のコードを関数としてまとめることを検討しましょう。これにより、コードの再利用性が高まり、保守が容易になります。

“`python
def create_sine_cosine_plot(x, y1, y2, title):
“””サインとコサインの折れ線グラフを作成する関数”””
fig, ax = plt.subplots()
ax.plot(x, y1, label=’sin(x)’)
ax.plot(x, y2, label=’cos(x)’)
ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
ax.set_title(title)
ax.legend()
ax.grid(True)
return fig, ax # 必要に応じてFigureとAxesオブジェクトを返す

関数を使ってグラフを作成

x = np.linspace(0, 10, 100)
fig, ax = create_sine_cosine_plot(x, np.sin(x), np.cos(x), ‘サインとコサインの比較’)
plt.show()
“`

可視化の目的を明確にする

グラフを作成する前に、「このグラフで何を伝えたいのか?」という目的を明確にすることが最も重要です。目的によって、選ぶべきグラフの種類、強調すべきデータ、使用すべき色や注釈が変わってきます。単にデータを見せるだけでなく、ストーリーを語るつもりでグラフを作成しましょう。

データの準備

Matplotlibで効果的なグラフを作成するには、元のデータが適切な形式(通常はNumPy配列やPandasのSeries/DataFrame)に整形されている必要があります。欠損値の処理、データのフィルタリング、集計など、可視化の前に必要なデータ前処理をきちんと行いましょう。

適切なグラフタイプの選択

データの種類(カテゴリ変数、数値変数、時系列データなど)や、示したい関係性(分布、比較、相関、構成比など)に応じて、最も適したグラフタイプを選択しましょう。
* 比較: 棒グラフ、折れ線グラフ
* 分布: ヒストグラム、箱ひげ図、密度プロット
* 相関: 散布図、ヒートマップ
* 構成比: 円グラフ、積み上げ棒グラフ
* 時系列: 折れ線グラフ

色の使い方

色の使い方はグラフの印象と分かりやすさに大きく影響します。
* 色の数を制限する: あまり多くの色を使うと、グラフがごちゃごちゃして見えます。
* 一貫性を持たせる: 同じ意味を持つデータ系列には、異なるグラフでも同じ色を使うようにすると、比較しやすくなります。
* 色覚多様性への配慮: カラーブラインドの方でも区別しやすいカラーパレットやカラーマップ(例: ColorBrewer, viridisなど)を選ぶことを検討しましょう。
* 強調: 特定の重要なデータポイントや系列を目立たせるために、コントラストの高い色を使います。

凡例とラベルの重要性

全てのグラフに、分かりやすいタイトル、軸ラベル、そして凡例(複数の系列がある場合)を必ず含めましょう。これにより、グラフを見る人が追加の説明なしに内容を理解できるようになります。軸ラベルには単位を含めることも重要です。

視覚的なノイズを減らす

グラフ上の不要な要素(過剰なグリッド線、不必要な装飾、読みにくいフォントなど)は、見る人の注意を散漫にさせ、伝えたいメッセージを不明瞭にします。シンプルかつクリーンなデザインを心がけましょう。

ファイル形式の選択 (PNG, JPEG, SVG, PDF)

グラフを保存する際、目的に応じて適切なファイル形式を選択します。
* PNG: Webページやプレゼンテーションなど、画面表示に適したビットマップ形式。背景透過をサポート。
* JPEG: 写真など、連続的なトーンの画像に適したビットマップ形式。圧縮率が高いが不可逆圧縮。グラフにはあまり適さない場合が多い。
* SVG: Webページやイラスト作成ソフトでの編集に適したベクター形式。拡大しても劣化しない。図形や線が多いグラフに最適。
* PDF: 文書や印刷に適したベクター形式(ビットマップを含むことも可能)。拡大しても劣化しにくく、フォント情報なども埋め込めるため、学術論文やレポートによく使われます。

高品質な印刷や拡大が必要な場合は、SVGやPDFのようなベクター形式を選ぶのが一般的です。

まとめ

この記事では、Pythonの強力なデータ可視化ライブラリであるMatplotlibの基本的な使い方から、様々な種類のグラフ作成、そして詳細なカスタマイズ方法までを網羅的に解説しました。

Matplotlibの基本的な概念であるFigureとAxesの関係、そしてオブジェクト指向APIの優位性を理解することで、より構造化されたコードで柔軟なグラフ作成が可能になることを学びました。

シンプルな折れ線グラフ、散布図、棒グラフの作成方法から始まり、軸の設定、タイトル、凡例、線のスタイル、マーカー、色の指定といったグラフの見た目を制御する多くの方法を習得しました。

また、plt.subplots()GridSpecを使った複数のグラフ配置、そしてヒストグラム、箱ひげ図、円グラフ、等高線図、ヒートマップ、3Dプロットといった多様なグラフタイプの基本的な使い方を知りました。

カラーマップを使った数値の色の表現や、テキスト、フォント、LaTeX数式の表示方法についても解説しました。

最後に、実践的なデータ可視化におけるヒントやベストプラクティスとして、目的の明確化、適切なグラフタイプの選択、効果的な色の使い方、ラベルや凡例の重要性、コードの構造化などについても触れました。

Matplotlibは非常に奥が深く、ここで紹介した機能はごく一部です。しかし、この記事で学んだ基本をしっかりと押さえれば、ほとんどの一般的なデータ可視化のニーズに対応できるはずです。

さらに高度な可視化や、より洗練されたデザインのグラフを作成したい場合は、Matplotlibの上に構築されたSeabornのようなライブラリも存在します。Seabornは、統計グラフ作成に特化しており、より少ないコードで美しいグラフを作成できることが多いですが、その基礎となるのはMatplotlibです。Matplotlibを学ぶことは、Seabornのような他のライブラリを理解する上でも非常に役立ちます。

ぜひ、この記事で学んだ知識を活かして、様々なデータを可視化し、その中に隠された洞察を発見してください。データを視覚化する旅は、エキサイティングでやりがいのあるものです。

Happy plotting!

参考文献/リソース

この記事が、あなたのMatplotlibを使ったデータ可視化の第一歩となり、今後の学習の助けとなれば幸いです。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール