Matplotlib 散布図と分布図 (Joint Plot) – チュートリアルと実例集

Python には多くのデータ可視化ライブラリがありますが、Matplotlib はその中でも最も人気のあるライブラリです。

Matplotlib の人気の理由はその信頼性と実用性にあり、少ないコードでシンプルなプロットから複雑なプロットまで作成することができます。

また、プロットは様々な方法でカスタマイズすることができます。

このチュートリアルでは、Matplotlib で、散布図と複数の分布図からなるジョイントプロットを、同じ Figure 上に作成する方法を説明します。

ジョイントプロットは、二変量データ間の関係や、その分布を同時に調べるために使用します。

注:この種のタスクは、ビルトインの jointplot() 関数を持つ Seaborn のようなライブラリにずっと適しています。

Matplotlib では、Seaborn の代わりに GridSpec と複数の Axes オブジェクトを使用して、手動でジョイントプロットを作成します。

データのインポート

ここでは、有名なアイリスのデータセットを使用します。

散布図で SepalWidthCmSepalLengthCm などの特徴量の関係を調べると同時に、分布図で萼片の長さや幅を考慮した Species 特徴量間の分布も調べることができるからです。

それでは、データセットをインポートして、見てみましょう。

import pandas as pd


df = pd.read_csv('iris.csv')
print(df.head())


この結果

   Id  SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm      Species
0   1            5.1           3.5            1.4           0.2  Iris-setosa
1   2            4.9           3.0            1.4           0.2  Iris-setosa
2   3            4.7           3.2            1.3           0.2  Iris-setosa
3   4            4.6           3.1            1.5           0.2  Iris-setosa
4   5            5.0           3.6            1.4           0.2  Iris-setosa


ここでは、SepalLengthCmSepalWidthCm の特徴量の二変量関係を調べると同時に、それらの分布も調べます。

これには2つの方法があります – 「種」を考慮するかしないかです。

種(Species)」を全く無視し、各花の分布のヒストグラムを単純にプロットすることができます。

一方、各花の分布図を色分けしてプロットし、「種」の違いも強調することができます。

ここでは、より単純な方、つまり Species を完全に無視することから始めて、両方の選択肢を探ってみることにします。

Matplotlib で単一クラスヒストグラムでジョイントプロットを作成する

最初のアプローチでは、花のインスタンスをロードして、そのままプロットします。

ここでは、図のレイアウトをカスタマイズするために GridSpec を使用して、3つの異なるプロットと Axes インスタンスに対応するスペースを確保します。

GridSpec` のコンストラクタを呼び出すには、PyPlot のインスタンスと一緒にインポートする必要があります。

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec


それでは、 Figure を作成して Axes オブジェクトを作成しましょう。

df = pd.read_csv('iris.csv')


fig = plt.figure()
gs = GridSpec(4, 4)


ax_scatter = fig.add_subplot(gs[1:4, 0:3])
ax_hist_y = fig.add_subplot(gs[0,0:3])
ax_hist_x = fig.add_subplot(gs[1:4, 3])


plt.show()


図にサブプロットを追加し、それらを配置するために GridSpec インスタンスを使用して、3つの Axes インスタンスを作成しました。

この結果、3つの空の Axes インスタンスを持つ Figure ができあがります。

これでレイアウトと位置決めができたので、あとはデータを Axes にプロットするだけです。

ここでは、SepalLengthCmSepalWidthCm の特徴を散布図として ax_scatter 軸に、それぞれの特徴を ax_hist_yax_hist_x 軸にプロットするようにスクリプトを更新してみましょう。

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec


df = pd.read_csv('iris.csv')


fig = plt.figure()
gs = GridSpec(4, 4)


ax_scatter = fig.add_subplot(gs[1:4, 0:3])
ax_hist_x = fig.add_subplot(gs[0,0:3])
ax_hist_y = fig.add_subplot(gs[1:4, 3])


ax_scatter.scatter(df['SepalLengthCm'], df['SepalWidthCm'])


ax_hist_x.hist(df['SepalLengthCm'])
ax_hist_y.hist(df['SepalWidthCm'], orientation = 'horizontal')


plt.show()


ax_hist_yorientationhorizontal` に設定し、散布図の右側に水平にプロットされるようにしました。

この結果、SepalLengthCmSepalWidthCm の特徴の関係、およびそれぞれの特徴の分布がジョイントプロットされます。

Matplotlib で複数クラスヒストグラムのジョイントプロットを行う

さて、もう1つのケースとして、花の「種」に対するこれらの特徴の分布を調べたいと思います。

このために、各軸に1つのヒストグラムを使用し、それぞれにすべての花のインスタンスを含めるのではなく、両方の軸にそれぞれの「種」のヒストグラムを重ねます。

そのためには、まず今まで使っていた DataFrame を、花の Species ごとに分解する必要があります。

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec


df = pd.read_csv('iris.csv')


setosa = df[df['Species']=='Iris-setosa']
virginica = df[df['Species']=='Iris-virginica']
versicolor = df[df['Species']=='Iris-versicolor']
species = df['Species']
colors = {
    'Iris-setosa' : 'tab:blue', 
    'Iris-versicolor' : 'tab:red',
    'Iris-virginica' : 'tab:green'
    }


ここでは、DataFrameSpecies 機能でフィルタリングして、3つのデータセットに分離しています。

setosavirginicaversicolor` の各データセットには、それぞれのインスタンスのみが含まれるようになります。

また、散布図とヒストグラムの両方で、それぞれのインスタンスを「種」に基づいて異なる色で表示したいと思います。

そのために、Species 機能の Series を切り出して、colors 辞書を作成します。

この辞書を使って、後でそれぞれの花の Species を色に map() することになります。

それでは、Figure, GridSpec, Axes のインスタンスを作成してみましょう。

fig = plt.figure()
gs = GridSpec(4, 4)


ax_scatter = fig.add_subplot(gs[1:4, 0:3])
ax_hist_y = fig.add_subplot(gs[0,0:3])
ax_hist_x = fig.add_subplot(gs[1:4, 3])


最後に、散布図とヒストグラムをプロットして、色と向きを設定します。

ax_scatter.scatter(df['SepalLengthCm'], df['SepalWidthCm'], c=species.map(colors))


ax_hist_y.hist(versicolor['SepalLengthCm'], color='tab:red', alpha=0.4)
ax_hist_y.hist(virginica['SepalLengthCm'], color='tab:green', alpha=0.4)
ax_hist_y.hist(setosa['SepalLengthCm'], color='tab:blue', alpha=0.4)


ax_hist_x.hist(versicolor['SepalWidthCm'], orientation = 'horizontal', color='tab:red', alpha=0.4)
ax_hist_x.hist(virginica['SepalWidthCm'], orientation = 'horizontal', color='tab:green', alpha=0.4)
ax_hist_x.hist(setosa['SepalWidthCm'], orientation = 'horizontal', color='tab:blue', alpha=0.4)


plt.show()


map()の呼び出しは、色のSeries` を生成します。

0       tab:blue
1       tab:blue
2       tab:blue
3       tab:blue
4       tab:blue
         ...
145    tab:green
146    tab:green
147    tab:green
148    tab:green
149    tab:green


scatter()関数のc` 引数に指定すると、この順序でインスタンスに色を適用し、各インスタンスにその種に対応する色を効果的に付けます。

ヒストグラムの場合は、単純に3つのプロットを作成し、それぞれの Species に対応する色をつけています。

ここでは、step ヒストグラムを選択し、alpha 値を微調整して、異なる外観の分布を作成することができます。

このコードを実行すると、次のような結果が得られます。

これで、それぞれの「種」は独自の色と分布を持ち、他の花とは別にプロットされるようになりました。

さらに、散布図と一緒に色分けされているので、本当に直感的なプロットで、簡単に読み解くことができます。

注意:赤と青のヒストグラムを構成するオレンジのような、重なり合った色が邪魔に感じる場合は、histtypestepに設定すると、塗りつぶした色を取り除くことができます。

結論

このガイドでは、Matplotlib でジョイントプロット (Scatter Plot) を描く方法を紹介しました。

この作業は、Seabornのようなジョイントプロットを内蔵したライブラリに適していますが、Matplotlibは、Seabornが簡単にこれらのプロットを作成できるようにするための基礎となるエンジンです。

もしあなたがデータ可視化に興味があり、何から始めたらよいかわからない場合は、Pythonによるデータ可視化に関する書籍の束をチェックしてみてください。

Pythonによるデータ可視化

データビジュアライゼーションで危険な存在になる

30日間無条件返金保証

初級から上級まで

定期的に無料で更新(最新更新は2021年4月)

ボーナスリソースやガイドを更新

Pythonでデータ可視化 MatplotlibとPandasは、Pythonの基礎知識を持つ全くの初心者が、PandasとMatplotlibを使って、単純なプロットからインタラクティブなボタンを持つアニメーションの3Dプロットまで、これらのライブラリで高度な作業をするための強力な基盤を構築できるように設計された書籍です。

本書は、Pythonの基本的な知識を持つ方を対象としています。

PandasとMatplotlibについて知っておく必要があることすべてを教えてくれる詳細なガイドです。

Pythonでデータ可視化」は、Pythonの初級~中級開発者向けの本で、Pandasを使った簡単なデータ操作から、MatplotlibやSeabornといったコアなプロットライブラリを取り上げ、Altairのような宣言的・実験的なライブラリの活用方法まで、幅広くガイドしています。

具体的には、11章にわたって、9つのPythonライブラリを取り上げています。

Pandas、Matplotlib、Seaborn、Bokeh、Altair、Plotly、GGPlot、GeoPandas、そしてVisPyです。

データビジュアライゼーションのユニークで実用的なガイドとして、あなたがキャリアで使うかもしれない多くのツールを紹介しています。

タイトルとURLをコピーしました