Python

Python seaborn チュートリアル マルチプロットグリッド プロット機能 構造化と構築 (1)

原文のドキュメントはこちらから。

多次元データを探索するとき、有用なアプローチは、データセットの異なるサブセットに同じプロットの複数のインスタンスを描画することである。この手法は、「格子」または「トレリス」プロットと呼ばれることもあり、「小さな倍数」の考え方に関連している。これにより、ビューアは複雑なデータセットに関する大量の情報を素早く抽出することができる。Matplotlibは、複数の軸を持つ図形を作成するための良いサポートを提供している。seabornは、プロットの構造をデータセットの構造に直接リンクするために、これの上に構築されている。

図形レベルの関数は、チュートリアルのこの章で説明したオブジェクトの上に構築されている。ほとんどの場合、これらの関数を使用することになるだろう。これらの関数は、各グリッド内の複数のプロットを同期させる重要な簿記を行う。この章では、基礎となるオブジェクトがどのように機能するか説明する。

条件付き小倍数

FacetGridクラスは、データセットのサブセット内で変数の分布や複数の変数間の関係を別々に可視化したい場合に便利だ。FacetGridは、行、列、色相の3つの次元まで描画することができる。最初の2つは、結果として得られる軸の配列と明らかに対応している。色相変数は、異なるレベルが異なる色でプロットされる深度軸に沿った第3の次元だと考えると良い。

relplot()、displot()、catplot()、および lmplot() のそれぞれは、内部的にこのオブジェクトを使用している。

このクラスは、データフレームとグリッドの行、列、色相の次元を形成する変数の名前でFacetGridオブジェクトを初期化することで使用される。これらの変数は、カテゴリカルまたは離散的なものでなければならず、変数の各レベルのデータは、その軸に沿ったファセットに使用される。例えば、Tipsデータセットでランチとディナーの違いを調査する。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(color_codes=True)

tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="time")

plt.show()

このようにグリッドを初期化すると、matplotlibの図と軸がセットアップされるが、その上には何も描画されない。

このグリッド上のデータを可視化するための主なアプローチは、FacetGrid.map()メソッドを使うことだ。これにプロット関数と、プロットするデータフレーム内の変数名を与える。ヒストグラムを使って、これらのサブセットのそれぞれのチップの分布を確認する。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(color_codes=True)

tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="time")
g.map(sns.histplot, "tip")

plt.show()

この関数は、図を描画し、軸に注釈を付ける。リレーショナルプロットを作成するには、複数の変数名を渡すだけだ。また、キーワード引数を指定でき、プロット関数に渡される。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(color_codes=True)

tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="sex", hue="smoker")
g.map(sns.scatterplot, "total_bill", "tip", alpha=.7)
g.add_legend()

plt.show()

クラスのコンストラクタに渡すことができるグリッドの外観を制御するためのオプションがいくつかある。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(color_codes=True)

tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, row="smoker", col="time", margin_titles=True)
g.map(sns.regplot, "size", "total_bill", color=".3", fit_reg=False, x_jitter=.1)

plt.show()

margin_titlesはmatplotlib APIでは正式にサポートしておらず、すべてのケースでうまく動作しないことに注意が必要。特に、現在のところ、プロットの外側にある凡例では使用できない。

図のサイズは、各ファセットの高さをアスペクト比と共に提供することで設定される。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(color_codes=True)

tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="day", height=4, aspect=.5)
g.map(sns.barplot, "sex", "total_bill", order=["Male", "Female"])

plt.show()

切子のデフォルトの順序は、DataFrame の情報から導き出されれる。切子を定義するために使用される変数がカテゴリ型を持っている場合、カテゴリの順序が使用される。そうでなければ、切子はカテゴリレベルの出現順になる。しかし、適切な*_orderパラメータで任意の切子次元の順序を指定することが可能。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(color_codes=True)

tips = sns.load_dataset("tips")
ordered_days = tips.day.value_counts().index
g = sns.FacetGrid(tips, row="day", row_order=ordered_days, height=1.7, aspect=4,)
g.map(sns.kdeplot, "total_bill")

plt.show()

任意のseabornカラーパレット(すなわち、color_palette()に渡すことができるもの)を提供できる。また、色相変数の値の名前をmatplotlibの有効な色にマップする辞書を使うこともできる。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(color_codes=True)

tips = sns.load_dataset("tips")
pal = dict(Lunch="seagreen", Dinner=".7")
g = sns.FacetGrid(tips, hue="time", palette=pal, height=5)
g.map(sns.scatterplot, "total_bill", "tip", s=100, alpha=.5)
g.add_legend()

plt.show()

1つの変数に多くのレベルの変数がある場合、列に沿ってプロットできるが、複数の行にまたがるように “ラップ “させることができる。この場合、行変数を使用できない。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(color_codes=True)

attend = sns.load_dataset("attention").query("subject <= 12")
g = sns.FacetGrid(attend, col="subject", col_wrap=4, height=2, ylim=(0, 10))
g.map(sns.pointplot, "solutions", "score", order=[1, 2, 3], color=".3", ci=None)

plt.show()

FacetGrid.map()を使ってプロットを描い場合(複数回呼び出すことができる)、プロットのいくつかの側面を調整したいことがある。また、FacetGridオブジェクトには、より高い抽象度で図を操作するためのメソッドがいくつかある。最も一般的なのは FacetGrid.set() で、他にも FacetGrid.set_axis_labels() のようなより専門的なメソッドがあり、これは内部のファセットが軸ラベルを持たないという事実を尊重している。例えば、以下のようになる。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(color_codes=True)

tips = sns.load_dataset("tips")
with sns.axes_style("white"):
    g = sns.FacetGrid(tips, row="sex", col="smoker", margin_titles=True, height=2.5)
g.map(sns.scatterplot, "total_bill", "tip", color="#334488")
g.set_axis_labels("Total bill (US Dollars)", "Tip")
g.set(xticks=[10, 30, 50], yticks=[2, 6, 10])
g.fig.subplots_adjust(wspace=.02, hspace=.02)

plt.show()

さらなるカスタマイズのために、アンダーリングのmatplotlib FigureオブジェクトとAxesオブジェクトを直接操作でき、それぞれfigとaxs(2次元配列)にメンバー属性として格納される。行や列の切子のない図を作成する場合、ax属性を使用して単一の軸に直接アクセスすることもできる。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(color_codes=True)

tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="smoker", margin_titles=True, height=4)
g.map(plt.scatter, "total_bill", "tip", color="#338844", edgecolor="white", s=50, lw=1)
for ax in g.axes.flat:
    ax.axline((0, 0), slope=.2, c=".2", ls="--", zorder=0)
g.set(xlim=(0, 60), ylim=(0, 14))

plt.show()