pandasのplotメソッドでグラフを作成しデータを可視化
pandas.Series
, pandas.DataFrame
のメソッドとしてplot()
がある。Pythonのグラフ描画ライブラリMatplotlibのラッパーで、簡単にグラフを作成できる。
Irisデータセットを例として、様々な種類のグラフ作成および引数の設定などをサンプルコード・結果とともに説明する。
- Irisデータセット
plot()
メソッドの基本的な使い方- 表示
- 画像ファイルとして保存
- オブジェクトとして操作
- 共通の設定
- サイズを変更
- 別々のサブプロットに描画
- サブプロットのレイアウト
- サブプロットのx軸, y軸の共通化
- プロットする列の指定
- グラフの種類
- 折れ線グラフ(line plot)
- 棒グラフ(bar plot)
- 箱ひげ図(box plot)
- ヒストグラム(histogram)
- カーネル密度推定(Kernel Density Estimation plot)
- 面グラフ(area plot)
- 散布図(scatter plot)
- 六角形ビニング図(hexbin plot)
- ビジュアライゼーションライブラリseabornを使ったグラフ作成
- ヒートマップ
- ペアプロット図(散布図行列)
各種ライブラリを以下のようにインポートする。
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
Irisデータセット
irisデータセットは機械学習でよく使われるアヤメの品種データ。
150件のデータがSetosa, Versicolor, Virginicaの3品種に分類されており、それぞれ、Sepal Length(がく片の長さ), Sepal Width(がく片の幅), Petal Length(花びらの長さ), Petal Width(花びらの幅)の4つの特徴量を持っている。
様々なライブラリにテストデータとして入っている。
- The Iris Dataset — scikit-learn 0.19.0 documentation
- [https://github.com/pandas-dev/pandas/blob/master/pandas/tests/io/data/csv/iris.csv](https://github.com/pandas-dev/pandas/blob/master/pandas/tests/io/data/csv/iris.csv
- https://github.com/mwaskom/seaborn-data/blob/master/iris.csv
pandas.DataFrame
として読み込む。
df = pd.read_csv('data/src/iris.csv', index_col=0)
print(df.head())
# sepal_length sepal_width petal_length petal_width species
# 0 5.1 3.5 1.4 0.2 setosa
# 1 4.9 3.0 1.4 0.2 setosa
# 2 4.7 3.2 1.3 0.2 setosa
# 3 4.6 3.1 1.5 0.2 setosa
# 4 5.0 3.6 1.4 0.2 setosa
species
列には3種類の品種が文字列で格納され、残り4つの列はそれぞれの特徴量が数値で格納される。
plot()メソッドの基本的な使い方
表示
pandas.Series
またはpandas.DataFrame
からplot()
メソッドを呼ぶとデフォルトでは折れ線グラフが描画される。
グラフ化されるのは数値の列のみで文字列の列は除外される。index
がx軸として使われる。
Jupyter Notebookの場合、先に%matplotlib inline
を実行しておくとグラフがインラインで表示される。
df.plot()
画像ファイルとして保存
画像ファイルとして保存する場合はplt.savefig()
、ファイル保存ではなくOSの画像表示プログラムで表示する場合はplt.show()
を使う。
繰り返しグラフを作成する場合はplt.figure()
で初期化しないと、前の結果が残ることがあるので注意。Jupyter Notebookでインライン表示する場合は特に初期化の必要はない。
また、繰り返しplt.figure()
を実行すると以下のような警告が出る場合がある。
RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface
(`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory.
(To control this warning, see the rcParam `figure.max_open_warning`). max_open_warning, RuntimeWarning)
plt.savefig()
のあとでplt.close('all')
を実行すればOK。
plt.figure()
df.plot()
plt.savefig('data/dst/pandas_iris_line.png')
plt.close('all')
オブジェクトとして操作
plot()
メソッドが返すのはMatplotlibのAxesSubplot
オブジェクト。
print(type(df.plot()))
# <class 'matplotlib.axes._subplots.AxesSubplot'>
デフォルトではアクティブなサブプロットに描画されるが、plot()
の引数ax
で任意のサブプロットを指定して描画できる。
上のpyplot
インターフェイスと同様のグラフを生成する例。
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
df.plot(ax=ax)
fig.savefig('data/dst/pandas_iris_line.png')
plt.subplots()
を使って複数のサブプロットを並べる例。
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(9, 6))
df.plot(ax=axes[0, 0], legend=False)
df.plot(ax=axes[1, 2], legend=False, kind='hist')
fig.savefig('data/dst/pandas_iris_line_axes.png')
軸axis
の細かい設定を調整したい場合などはこちらのオブジェクト指向インターフェイスを使う。
なお、引数の設定、グラフの種類によってはplot()
はMatplotlibのAxesSubplot
オブジェクトを要素とするNumPy配列numpy.ndarray
を返すこともあるので注意。
共通の設定
plot()
では様々な種類のグラフをプロットできる。まず共通の設定を説明する。
サイズを変更
生成される画像のサイズはfigsize
(単位: インチ)とdpi
(インチ当たりのドット数)で決定される。
それぞれ以下のように確認および変更ができる。
figsize
はpandasのplot()
メソッド、または、plt.figure()
, plt.subplots()
の引数として指定する。
current_figsize = mpl.rcParams['figure.figsize']
print(current_figsize)
# [6.0, 4.0]
plt.figure()
df.plot(figsize=(9, 6))
plt.savefig('data/dst/pandas_iris_line_figsize.png')
plt.close('all')
dpi
はsavefig()
の引数として指定する。
current_dpi = mpl.rcParams['figure.dpi']
print(current_dpi)
# 72.0
plt.figure()
df.plot()
plt.savefig('data/dst/pandas_iris_line_dpi.png', dpi=current_dpi * 1.5)
plt.close('all')
各列を別々のサブプロットにプロット: 引数subplots
引数subplots=True
とすると各列が別々のサブプロットにプロットされる。
以降のサンプルコードではplt.figure()
, plt.savefig()
, plt.close
を省略する。
df.plot(subplots=True)
この場合、AxesSubplot
オブジェクトを要素とするNumPy配列numpy.ndarray
が返される。
print(type(df.plot(subplots=True)))
print(type(df.plot(subplots=True)[0]))
# <class 'numpy.ndarray'>
# <class 'matplotlib.axes._subplots.AxesSubplot'>
サブプロットのレイアウト: 引数layout
引数layout
にサブプロットの行数、列数をタプルで指定できる。
df.plot(subplots=True, layout=(2, 2))
サブプロットのx軸, y軸の範囲の共通化: 引数sharex, sharey
引数sharex
, sharey
をTrue
とすると、それぞれx軸、y軸の範囲が共通化される。
df.plot(subplots=True, layout=(2, 2),
sharex=True, sharey=True)
プロットする列の指定: 引数x, y
これまでの例のように、デフォルトではpandas.DataFrame
からplot()
メソッドを呼ぶと、数値の列すべてがプロットされ、index
がx軸として使われる。
引数x
, y
に列名を指定することでx軸, y軸としてプロットする列を選択できる。例は折れ線グラフなのでよく分からない結果となるが、散布図などの場合には重要な設定。散布図については後述。
df.plot(x='sepal_length', y='sepal_width')
x
のみ指定した場合は、残りの列がy軸としてプロットされる。
df.plot(x='sepal_length')
y
のみ指定した場合は、x軸がindex
、指定した列がy軸としてプロットされる。
df.plot(y='sepal_length')
引数x
, y
にリストで複数の列名を指定すると警告UserWarning
が出る。
# df.plot(y=['sepal_length', 'sepal_width'])
# UserWarning: Pandas doesn't allow columns to be created via a new attribute name
複数の列を重ねてプロットしたい場合は、1つ目のplot()
で取得できるAxesSubplot
を2つ目以降のplot()
の引数ax
に指定する。
ax = df.plot(y='sepal_length')
df.plot(y='sepal_width', ax=ax)
プロットに使う列のみを選択したpandas.DataFrame
でplot()
メソッドを呼んでも同じ結果が得られる。こっちのほうが楽かもしれない。
df[['sepal_length', 'sepal_width']].plot()
そのほか見た目の設定
そのほか、
- 引数
title
: グラフタイトル - 引数
grid
: グリッドの有無 - 引数
colormap
: 色 - 引数
legend
: 凡例の有無 - 引数
alpha
: 透過率(0〜1)
などが設定できる。
df.plot(title='Iris Data Set',
grid=True,
colormap='Accent',
legend=False,
alpha=0.5)
colormap
で指定できる色(カラーマップ)の種類は以下のMatplotlibの公式サイトを参照。
グラフの種類: 引数kind
引数kind
でグラフの種類を指定できる。
'line'
: 折れ線グラフ(line plot)'bar'
: 垂直棒グラフ(vertical bar plot)'barh'
: 水平棒グラフ(horizontal bar plot)'box'
: 箱ひげ図(boxplot)'hist'
: ヒストグラム(histogram)'kde'
,'density'
: カーネル密度推定(Kernel Density Estimation plot)'area'
: 面グラフ(area plot)'scatter'
: 散布図(scatter plot)'hexbin'
: hexbin plot'pie'
: 円グラフ(pie plot)
バージョン0.17.0
から、上記のグラフの種類をplot()
メソッドのアクセサとして記述できるようになった。
例えばdf.plot(kind='line')
とdf.plot.line()
は同じ。
df.plot(kind='line')
df.plot.line()
plot.line()
でもここまで説明してきたplot()
の引数がそのまま使える。
df.plot.line(subplots=True, layout=(2, 2))
それぞれのグラフの種類に対応するMatplotlibのメソッドの引数もキーワード引数として設定できる。
折れ線グラフ(line plot)
折れ線グラフはplot.line()
。
線種や色、マーカーは引数style
に文字列'[color][marker][line]'
で指定する。
color
:r
(赤),g
(緑),b
(青),k
(黒)などmarker
:o
(丸),.
(点),s
(四角),+
(プラス)などline
:-
(破線),--
(破線),:
(点線)など
例えば赤い破線に四角のマーカーは'rs--'
。color
, marker
, line
をすべて含む必要はなく、省略も可能。
それぞれの種類一覧は以下のMatplotlib公式サイト参照。中段のNoteに書いてある。
各プロットに対して個別に指定したい場合は引数style
に文字列のリストを指定する。
df.plot.line(style=['r--', 'b.-', 'g+', 'k:'])
棒グラフ(bar plot)
垂直棒グラフはplot.bar()
, 水平棒グラフはplot.barh()
。
行数が多いと見にくいので最初の5行分のデータのみ使用している。
df[:5].plot.bar()
df[:5].plot.barh()
引数stacked=True
とすると積み上げ棒グラフになる。
df[:5].plot.bar(stacked=True)
棒グラフ独自の引数はMatplotlibの公式サイト参照。
- matplotlib.pyplot.bar — Matplotlib 2.2.2 documentation
- matplotlib.pyplot.barh — Matplotlib 2.2.2 documentation
箱ひげ図(box plot)
箱ひげ図はplot.box()
。
最小値、第1四分位点、中央値、第3四分位点、最大値が表される。丸は外れ値。
df.plot.box()
箱ひげ図独自の引数はMatplotlibの公式サイト参照。
ヒストグラム(histogram)
ヒストグラムはplot.hist()
。
plt.savefig('data/dst/pandas_iris_hist.png')
透過率は引数alpha
。
df.plot.hist(alpha=0.5)
引数stacked=True
で積み上げヒストグラム。
df.plot.hist(stacked=True)
ヒストグラム独自の引数はMatplotlibの公式サイト参照。
引数bins
で分割数を指定したり、histtype
でタイプを指定したり、orientation
で横向きにしたりできる。
df.plot.hist(bins=20, histtype='step', orientation='horizontal')
カーネル密度推定(Kernel Density Estimation plot)
カーネル密度推定の分布図はplot.kde()
。
線の種類、色は折れ線グラフと同様、引数style
で指定できる。上の折れ線グラフの項を参照。
df.plot.kde(style=['r-', 'g--', 'b-.', 'c:'])
面グラフ(area plot)
面グラフはplot.area()
。
デフォルトで積み上げ面グラフとなる。積み上げを無効にしたい場合は引数stacked=False
。
df.plot.area()
散布図(scatter plot)
散布図はplot.scatter()
。
x軸、y軸としてプロットする列の列名をそれぞれ引数x
, y
に指定する。
df.plot.scatter(x='sepal_length', y='petal_length', alpha=0.5)
上の共通の設定の項で説明したように、複数のプロットを重ねる場合は1つ目のplot()
で取得できるAxesSubplot
を2つ目以降のplot()
の引数ax
に指定する。
マーカーの種類は引数marker
、色は引数c
、サイズは引数s
で指定する。c
とs
はリストで指定することも可能。
そのほか散布図独自の引数はMatplotlibの公式サイト参照。
ax = df.plot.scatter(x='sepal_length', y='petal_length', alpha=0.5)
df.plot.scatter(x='sepal_length', y='petal_width',
marker='s', c='r', s=50, alpha=0.5, ax=ax)
なお、折れ線グラフの引数style
でマーカーを指定して線種を省略すると散布図と同様のグラフが描画できる。こっちのほうが楽かもしれない。お好みで。
df.plot.line(x='sepal_length',
style=['ro', 'g+', 'bs'], alpha=0.5)
六角形ビニング図(hexbin plot)
日本語の正しい名称を知らないが、散布図での六角形のエリアに入る点の数を色の濃さで表したグラフ。同じ位置に多数の点が重なってプロットされるようなデータの分布が見やすい。
散布図と同様にx軸、y軸としてプロットする列の列名をそれぞれ引数x
, y
に指定する。
hexbin独自の引数はMatplotlibの公式サイト参照。
引数gridsize
はx軸方向の六角形の数。小さくなると六角形が大きく、粗いグラフになる。
df.plot.hexbin(x='sepal_length', y='petal_length',
gridsize=15, sharex=False)
デフォルトだとx軸のラベルが表示されないpandasのバグがある。バージョン0.22.0
時点でまだFixされていないが、sharex=False
とすればとりあえず表示されるようになる。
円グラフ(pie plot)
円グラフはplot.pie()
。
Irisのデータだとよく分からないので別のデータを例とする。
df_pie = pd.DataFrame([[1, 50], [2, 20], [3, 30]],
index=['a', 'b', 'c'], columns=['ONE', 'TWO'])
print(df_pie)
# ONE TWO
# a 1 50
# b 2 20
# c 3 30
pandas.DataFrame
に対しては引数subplots=True
として列毎に個別にプロットしないとエラーになる。
df_pie.plot.pie(subplots=True)
AxesSubplot
オブジェクトを要素とするNumPy配列numpy.ndarray
が返される。
print(type(df_pie.plot.pie(subplots=True)))
print(type(df_pie.plot.pie(subplots=True)[0]))
# <class 'numpy.ndarray'>
# <class 'matplotlib.axes._subplots.AxesSubplot'>
特定の列の円グラフを生成したい場合は、列を指定してplot.pie()
を呼ぶ。
df_pie['ONE'].plot.pie()
ビジュアライゼーションライブラリseabornを使ったグラフ作成
ビジュアライゼーションライブラリseabornを使うとそのほかの種類のグラフを作成できる。
ヒートマップ
二次元データからヒートマップを作成できる。
pandas.DataFrame
を使うと列名・行名がそのままx軸・y軸のラベルになる。
下の例はIrisではなく別のデータの各列間の相関係数を可視化したもの。
詳細は以下の記事を参照。
ペアプロット図(散布図行列)
ペアプロット図(散布図行列)も作成できる。
列同士の関係をざっくり確認するのに便利。
詳細は以下の記事を参照。