matplotlib https://matplotlib.org/ は, PythonならびにNumPyのためのグラフ描画ライブラリである.
最初の例題として用いるのはiris(アヤメ)のデータである.
まずはpandasを用いてデータを読んでおく.
%matplotlib inline
としておくと,描画が画面にすぐに表示されるようになる.
import pandas as pd
%matplotlib inline
df = pd.read_csv(
"http://logopt.com/data/iris.data",
names=["sepal length", "sepal width", "petal length", "petal width", "class"],
)
df.head()
df.hist(bins=30);
問題 (SAT,GPA)
http://logopt.com/data/SATGPA.csv データを読み込み,2種類のSATの成績とGPAのヒストグラムを描画せよ. また,引数のbinsを色々変えてみよ.
pokemon = pd.read_csv("http://logopt.com/data/poke.csv", encoding="utf-8", index_col=0)
pokemon.head()
df.plot.scatter(x="sepal length", y="petal length")
問題 (ダイヤモンド)
http://logopt.com/data/Diamond.csv からダイアモンドの価格データを読み込み,カラット (carat) と価格 (price) の散布図を描け.
df.plot.area();
# 面積図
df.plot.bar();
# 棒グラフ
df.plot.box();
# 箱ひげ図
df.plot.density();
# カーネル密度推定(kdeと同じ)
df.plot.hexbin(x="sepal length", y="petal length", gridsize=30);
# 6角形格子図(散布図と同様に,x,y軸を入れる.)
df.plot.line();
# 線グラフ df.plot()でも同じ
多次元データ 1: 並行座標図
散布図では3次元までの図を可視化できる(3次元の場合の方法については教科書参照)が,4次元以上だと人間の目では無理だ.
多次元データを可視化するための方法として並行座標図がある.
これは散布図の $y$ 軸を $x$ 軸と並行にしたものである.複数の $y$ 軸があっても大丈夫だが,あまり多いとよく分からなくなる.
pandasではplottingにあるparallel_coordinates 関数を用いて並行座標図を描画できる.
第1引数はデータフレームであり,第2引数は分けて描画したいクラスを表す列名を与える.
並行座標図は,比例関係は平行な直線で,反比例関係は1つの点で交わる直線群で描画する.
例として,$x= 0,1,2, \ldots,9$,$y=2x$, $z=10-x$ を描画してみよう.
from pandas.plotting import parallel_coordinates
data = [] # x,y,zを入れたリストを作成
for i in range(10):
row = [i, 2 * i, 10 - i, "dummy"] # クラス名を指定するためにダミーの列を最後に追加
data.append(row)
testdf = pd.DataFrame(data)
testdf
parallel_coordinates(testdf, 3);
# ダミーの列の名前は 3
iris = pd.read_csv(
"http://logopt.com/data/iris.data",
names=["sepal length", "sepal width", "petal length", "petal width", "class"],
)
多次元データ 2: Andrew曲線
多次元データを可視化するためのもう1つの方法としてAndrew曲線がある.
これは.多次元データ $x_1,x_2,\ldots$ をフーリエ曲線
$$ f_x(t) = \frac{x_1}{\sqrt 2} + x_2 \sin(t) + x_3 \cos(t) + x_4 \sin(2t) + x_5 \cos(2t) + \cdots $$で変換し,$-\pi < t < \pi$ の間に描画したものである.
pandasではplottingにあるandrews_curves 関数を用いて並行座標図を描画できる.
第1引数はデータフレームであり,第2引数は分けて描画したいクラスを表す列名を与える.
例として,$x= 0,1,2, \ldots,9$,$y=2x$, $z=10-x$ を描画してみよう.
from pandas.plotting import andrews_curves
andrews_curves(testdf, 3);
データ解析用描画パッケージ seaborn
seaborn https://seaborn.pydata.org/ を用いることによって,さらに簡単にデータ解析ができ,描画も綺麗になる.
まずはseabornパッケージをsnsという別名で読み込んでおく.
import seaborn as sns
%matplotlib inline
df = pd.read_csv(
"http://logopt.com/data/iris.data",
names=["sepal length", "sepal width", "petal length", "petal width", "class"],
)
df.head()
sns.displot(df["sepal length"], bins=20, rug=True, kde=True);
問題 (SAT, GPA)
http://logopt.com/data/SATGPA.csv データを読み込み,GPAの分布をdistplotを用いて描画せよ.
sns.jointplot(x="sepal length", y="petal length", data=df, kind="scatter");
データフレームに含まれる複数の列間の散布図を一度に描画するにはpairplotを用いる.
引数としてhue(色調)をとることができ,色を変えたい列名(以下の例ではアヤメの種類(class)を指定して描画している.
sns.pairplot(df, hue="class");
問題 (SAT,GPA)
- http://logopt.com/data/SATGPA.csv データを読み込み,MathSATとGPAの関係をjointplotを用いて描画せよ.
- http://logopt.com/data/SATGPA.csv データを読み込み,MathSAT, VerbalSAT, GPAの相互関係をpairplotを用いて描画せよ.
tips = sns.load_dataset("tips")
tips.head()
sns.lmplot(x="total_bill", y="tip", data=tips, row="smoker", col="sex", hue="time");
カテゴリカルデータの分析
カテゴリカルデータ別に集計したい場合には,catplotを用いると便利だ.
引数は以下の通り.
- x: $x$軸
- y: $y$軸
- data: データフレーム
- row: 行名
- col: 列名
- hue: 色調
- kind: グラフの種類 (point, bar, count, box, violin, strip)
- split: バイオリン図(violin:箱ひげ図の拡張)の場合だけ有効で,Trueのとき左右に色調を分けて描画する.
以下の例では,tipsデータに対し,日ごと(x)のチップ(y)を喫煙者か否か(row="smoker"),性別(col="sex"), 昼食か夕食か(hue="time")ごとにバイオリン図で描画している.
sns.catplot(
x="day",
y="tip",
data=tips,
row="smoker",
col="sex",
hue="time",
split=True,
kind="violin",
);
titanic = sns.load_dataset("titanic")
titanic.head()