Pandas:図示#

in English or the language of your choice.

説明#

import numpy as np
import pandas as pd
import japanize_matplotlib

# 警告メッセージを非表示
import warnings
warnings.filterwarnings("ignore")

プロット用のパッケージMatplotlibを紹介したが,実はPandasDataFrameSeriesにはメソッドplot()が備えられており,それを使えば基本的なプロットをより簡単なコードで実現できる。裏で動いているのはMatplotlibであり,より複雑な図を作成する場合は、Matplotlibのコードを直接書くことが必要になるだろうが,手っ取り早くプロットしたい場合には重宝する手法である。詳細は参考サイト(英語)を参考にして欲しいが,ここでは基本的な使い方を紹介する。

次のdfを使って説明する。

dic = {'X':[10, 20, 30],
       'Y':[5.0, 30.0, 15.0],
       'Z':[3.0, 2.0, 5.0]}
df = pd.DataFrame(dic)
df
X Y Z
0 10 5.0 3.0
1 20 30.0 2.0
2 30 15.0 5.0

プロット方法#

DataFrame#

プロット方法は簡単で,次の基本構文となる。

df.plot(x="列ラベル", y="列ラベル")
  • x:横軸に使う列ラベル(文字列)

  • y:縦軸に使う列ラベル(文字列、複数の場合はリスト)

df.plot(x='X', y='Y')
<Axes: xlabel='X'>
_images/70e0030f022aa7c84f7a76f065b13713badccd7472ff6b919df83ae005a69737.png
  • 凡例は自動的に表示され,列ラベルが使われる。次の引数を追加すると凡例は非表示になる。

legend=False
  • 図の上に文字が表示されるが,表示したくない場合は最後に;を加えるか次の行にpassと書くと良いだろう。

縦軸に複数の変数を表示したい場合は,次のようにリストとして指定する。

df.plot(x="列ラベル", y=["列ラベル1", "列ラベル2"])
df.plot(x='X', y=['Y', 'Z'])
<Axes: xlabel='X'>
_images/cf6e4cb47ca9e9d4e6658fcf3d9604380ef69bde006772bded7908f29c31c4d3.png

上の例では引数xyを指定したが,xを指定しない場合はどうなるか試してみよう。

df.plot(y='Y')
pass
_images/498af4d88317605a5ccd2f1d83593ba26971d2ada831a45020cc76f0183bd934.png

縦軸はYだが,横軸には行インデックスが使われることになる。この場合,行インデックスがfloatとして表示されている。

では、引数なしで実行するとどうなるだろう。

df.plot()
pass
_images/df3e477dc733b27b99992ba6896d183ba2e273bf678c33a60f51913b2a04ee94.png

縦軸には全ての列が使われ、横軸には行インデックスが使われている。

Series#

次に,Seriesを考えてみよう。まず,2つのSeriesを作成しよう。

sy = df['Y']
sy
0     5.0
1    30.0
2    15.0
Name: Y, dtype: float64
sz = df['Z']
sz
0    3.0
1    2.0
2    5.0
Name: Z, dtype: float64

両方ともdfの行インデックスが引き継がれている。

Seriesにもメソッド.plot()が実装されているが次の点を覚えておこう。

  • 列が1つしかないため,引数xyを指定する必要はない。

syをプロットしてみよう。

sy.plot()
pass
_images/d845c274394e9ebf63aa82b32df43b28d450337e975a5ad4b173abba3c21679e.png

横軸には行インデックスがfloatとして使われており,Seriesの場合,凡例は自動的には表示されない。 次の引数を使うと凡例を表示することができる。

legend=True

更に,次の点でDataFrameを使う場合と異なる。syszを続けて書いて実行してみよう。

sy.plot(legend=True)
sz.plot(legend=True)
pass
_images/df25aaf3e4c40eef004427d9964cc21492b3b42b38bfbf91e1ca0b4afc847970.png

Seriesの場合,連続してコードを書くと一つの図に表示することができる。この特徴は,次に説明する「飾り付け」を各データ毎別々に設定する際に便利な機能と感じる人もいるだろう。

引数とメソッド#

基本的な引数#

plot()には様々な引数があり図に「飾り付け」をすることができる。詳しくはこのリンクを参照することにして,ここでは基本的な引数だけを紹介する。

  • style:線のスタイル(複数ある場合はリストにして列の順番で指定する;----.:

  • linewidth or lw:線の幅

  • color:色(リストにして列の順番で指定する; 参照サイト

    • rは赤

    • kは黒

    • gはグリーン

  • marker:観測値のマーカー(o.>^などがある; 参照サイト

  • markersize:マーカーの大きさ

  • fontsize:横軸・縦軸の数字のフォントサイズの設定

  • figsize:図の大きさ

    • figsize=(キャンバスの横幅、キャンバスの縦の長さ)

  • legend:凡例の表示を指定

    • DataFrameの場合はデフォルトはTrue

    • Seriesの場合はデフォルトはFalse

    • 複数の図を表示する際は下で説明する「軸」のメソッドとして指定することもできる。

  • label:凡例の表現を指定

  • grid:グリッド表示(ブール型;デフォルトはFalse)

    • 複数の図を表示する際は,この引数は使わずに下で説明する「軸」のメソッドとして指定する。

  • ax:プロットする「軸」を指定する。

    • 1つの「軸」に複数の図を表示する際に使う(後で使い方を説明する)。

df.plot( # 引数 x, y は省略
        style=[':','--','-'],
        linewidth=2,
        color=['r','k','g'],
        marker='o',
        markersize=10,
        fontsize=15,
        figsize=(8, 4),   # 8は横軸、4は縦軸のサイズ
        legend=False,
        grid=True,
        )
pass
_images/49f96d08502f0021744a3cda8ee4da0391f1ede492f1963de2a31a80810b7850.png

タイトルとラベルのサイズの調整#

タイトルのフォント・サイズの指定,横軸と縦軸のラベルとフォント・サイズの指定をおこなう場合は、plot()の引数ではなく下で説明する方法でおこなう。この方法を理解するために、Pandas(実はMatplotlib)が表示する図はFig. 2で示している階層的な構造となることをイメージして欲しい。ここで重要なのは「キャンバス」と「軸」の違いである。

_images/figure_axes_pandas.png

Fig. 2 「キャンバス」と「軸」の関係#

  1. 「キャンバス」とは実際に表示される領域であり,実際には表示されない「透明のキャンバス」である。

    • figurefigなどの変数名や引数名があれば、「キャンバス」を指していると理解すれば良いだろう。

  2. 「軸」とは1つの図を表示する「キャンバス」上の区域である。

    • axaxesなどの変数名があれば、「軸」を表していると理解すれば良いだろう。

    • 「キャンバス」上に複数の図を表示する場合は複数の「軸」が必要となる。

    • 「軸」に図のタイトルや縦軸・横軸のラベルなどを追加することになる。

「軸」の中にメソッド.plot()を使いグラフを表示することになる。

従って,概ね次のように理解して良いだろう。

  • 上で説明した「基本的な引数」は上の図のピンクのエリア内での変更となる。

    • figsizeは「キャンバス」の大きさを指定する引数だが,メソッドplot()は自動で「キャンバス」を作成するためplot()内で変更できるようになっている。

  • タイトルや縦・横軸ラベルは「軸」のメソッドを使い変更する。

では実際に手順を説明する。

  • df.plot()は自動で「キャンバス」と「軸」を作成すると同時に「軸」を返す。それを変数(例えば,ax)に割り当てる。

  • axのメソッドを使って以下を設定する。

    • タイトル:.set_title()

    • 横軸ラベル:.set_xlabel()

    • 縦軸ラベル:.set_ylabel()

実際にそれらの引数を使ってプロットしてみよう。

ax = df.plot( # 引数 x, y は省略
             grid=True,
             style=[':','--','-'],
             marker='o',
             fontsize=15,
             )
ax.set_title('A Large Title', size= 30)     # タイトルの設定
ax.set_xlabel('Horizontal Axis', size=20)   # 横軸ラベルの設定
ax.set_ylabel('Vertical Axis', size=20)     # 縦軸ラベルの設定
pass
_images/e3cdacc72392941ea9674c84530ca5297ed51be39a212881ba4ee75141f4593f.png

「軸」を指定してプロットする場合#

上で「軸」のメソッドとしてタイトルなどを追加できることを説明したが,plot()の引数として「軸」を指定して図を追加することができる。次のコードを考えてみよう。

ax_ = df.plot(x='X', y='Y')     #1
df.plot(x='X', y='Z', ax=ax_)   #2
pass
_images/cf6e4cb47ca9e9d4e6658fcf3d9604380ef69bde006772bded7908f29c31c4d3.png
  • #1の右辺では「キャンバス」と「軸」が自動生成され,その内「軸」のみが返され変数ax_に割り当てられている。

  • #2plot()の引数axは「軸」を指定する引数であり,それにax_を設定している。即ち,Zを「軸」ax_にプロットすることを指定している。このコードには2つの利点がある。

    1. XYと異なる「飾り付け」をZに簡単に施すことができる。

    2. 2行目にdf0ではなく別のDataFrameを使うことも可能となる。

もちろん,タイトルや軸ラベルのメソッドをつけ加えることも可能である。

ax_ = df.plot(x='X', y='Y',
              marker='o', markersize=10, label='Yのデータ')
df.plot(x='X', y='Z', ax=ax_,
        marker='^', markersize=15, label='Zのデータ')
ax_.set_title('This is a title', size=20)
ax_.set_xlabel('Horizontal axis', size=15)
ax_.set_ylabel('Vertical axis', size=15)
ax_.grid()
pass
_images/06c59a5656c10bb35f06695dcf0e4b6c7775cec79d5f24bcb78c29f9ab5d9541.png

また上のコードの最後に次の行を付け加えている。

  • ax_.grid():グリッド線を表示するメソッド。

    • 1つの「軸」にplotを複数回適用する場合,個々のplotの引数grid=Trueを使わずにax_.grid()を指定すると分かりやすいですコードになる。

図を並べる#

図を縦に並べるにはsubplots=Trueを指定する。

df.plot(x='X', subplots=True)
pass
_images/9fd6374e13773a9f2f33bb4624847b4221db27eec4d4a274154bc11d3958ee6e.png

図を横に並べるにはlayout=(1,2)を付け加える。layoutは図の配置を行列のように考えて指定し、1は行の数であり、2は列の数。

layout(行の数、列の数)
df.plot(x='X', subplots=True, layout=(1,2), figsize=(8,3))
pass
_images/458e2e14efe8bd3e216eb9b41e10a38d62e33272193d580f9b720c07740f2146.png

図を並べる際も引数xを省略すると,横軸には行インデックスが使われることになる。

2軸グラフ#

左縦軸をYに,右縦軸をZに使うとしよう。その場合,引数secondary_yZを設定する。

df.plot(x='X', secondary_y='Z')
pass
_images/d6a05a7a6cacb39f7b1260cacedad5f16249261d3a809472ae85c00105a6bf49.png

別々の飾り付けをする場合は次のようにすると良いだろう。

ax_ = df.plot(x='X', y='Y')
df.plot(x='X', y='Z',
        ax=ax_,            #1
        secondary_y=True,  #2
        marker='^',        #3
        markersize=10,     #4
        linestyle=':',     #5
        )
pass
_images/47974bd3fb1557cddb48a21a31e8946c0777f5178da0e0b5e119d17d35e77ac1.png

上のコードとの主な違い:

  • #1ax=ax_:「軸」ax_Zをプロットする。

  • #2secondary_y=TrueZを右軸に使うことを指定する。

  • #3#5Zの飾り付け

日本語#

2つ方法を紹介するが、japanize_matplotlibを使う方法がより簡単であろう。

japanize_matplotlib#

使い方は到って簡単で、Pandasと同様にインポートするだけである。

import japanize_matplotlib
ax = df.plot( # 引数 x, y は省略
            grid=True,
            style=[':','--','-'],
            marker='o',
            fontsize=15,
            )
ax.set_title('縦横タイトル', size= 30)
ax.set_xlabel('横軸', size=20)
ax.set_ylabel('縦軸', size=20)
pass
_images/20eb35d3343e3c783908cd7aef99717dc7cda03fdd6ce390deea941f0c8a4d8b.png

フォントを指定する#

2つの方法:

  1. フォントはインストールせず、PC内にあるフォントを指定する。

  2. フォントをインストールする方法

方法1の場合、以下で説明に使う変数jfontにフォントを指定する。 * Macの場合、例えばAppleGothic * Windowsの場合、例えばYu Gothic * この方法では一部の日本語が文字化けする場合がある。

方法2の場合:

  • このサイトから次の内の1つをダウンロードする。

  • このサイトに従ってインストールする。

  • 次の両方もしくは1つがPCにインストールされる

    • IPAexMincho(IPAex明朝)

    • IPAexGothic(IPAexゴシック)

上の例を使い、設定方法の例を示す。

jfont = 'IPAexGothic'    #1

ax = df.plot( # 引数 x, y は省略
             grid=True,
             style=[':','--','-'],
             marker='o',
             fontsize=15,
             )
ax.set_title('縦横タイトル', size= 30, fontname=jfont)   #2
ax.set_xlabel('横軸', size=20, fontname=jfont)          #3
ax.set_ylabel('縦軸', size=20, fontname=jfont)          #4
ax.legend(prop={'family':jfont, 'size':17})            #5
pass
_images/ef0c4d909c556a6cb2bd80fafc0a2e591ba0b99ae65f5ef6d41c2a6dce1e3f0f.png
  • #1: 使用するフォントをjfontに割り当てる。

  • #2: 引数fontnamejfontを指定する。タイトルのフォントが変更される。

  • #3: 引数fontnamejfontを指定する。横軸名のフォントが変更される。

  • #4: 引数fontnamejfontを指定する。縦軸名のフォントが変更される。

  • #5legendは他と設定方法が異なる。

    • propはフォントのプロパティを設定する引数であり、辞書で指定する。

    • キーfamilyに値jfontを指定する。凡例のフォントが変更される。

    • キーsizeに数値を設定してフォントの大きさが変更される。

この例では個別にフォントを設定したが、一括で全てのフォントを変更する方法もあるが説明は割愛する。

マクロ経済学の例#

投資関数#

実質利子率rによって投資がどのように変化するかを考えてみよう。まず投資関数を次のように仮定する。

def investment(r):
    return 100/(1+r)**50
  • 100:実質利子率が0の場合の投資

実質利子率は次のarrayで与えられるとする。

r_arr = np.arange(0.01,0.11,0.01)
r_arr
array([0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1 ])

次に関数investmentr_arrを使い投資のarrayを作成しよう。

inv_arr = investment(r_arr)
inv_arr
array([60.80388247, 37.15278821, 22.81070798, 14.07126153,  8.7203727 ,
        5.42883618,  3.39477594,  2.13212286,  1.34485389,  0.85185513])

これらのデータを使いDataFrameを作成する。

df_inv = pd.DataFrame({'investment':inv_arr,
                       'interest_rate':r_arr})

最初の5行を表示する。

df_inv.head()
investment interest_rate
0 60.803882 0.01
1 37.152788 0.02
2 22.810708 0.03
3 14.071262 0.04
4 8.720373 0.05

ではプロットしてみよう。

df_inv.plot(x='interest_rate', y='investment')
pass
_images/e02798c8a3fe7674a31f00b8a20cac62fc60fea4164fa5cd9c05a70d3ca061e0.png

将来価値#

x万円を実質年率r%の利息を得る金融商品に投資し,t年間の将来価値(期首の値)をリストで示す関数は以下で与えられた。

def calculate_futre_value(x, r, t):
    
    value_list = [x]           # 初期値が入ったリスト
    
    for year in range(1,t+1):  # 1からtまでの期間
        x = x*(1+r)            # 来期のxの値の計算
        value_list.append(x)   # リストに追加
    
    return value_list          # リストを返す

これを使い,

  • x=100

  • t=30

の下で実質利子率が次のリストで与えられる値を取る場合の将来価値を図示する。

r_list = [0.01, 0.03, 0.06]   # 実質利子率のリスト
dic = {}                      # 空の辞書

for r in r_list:
    dic['r='+str(r)] = calculate_futre_value(100, r, 30)  # 辞書に追加

df_future = pd.DataFrame(dic) # DataFrameの作成

dic['r='+str(r)]の説明:

  • str(r)r_listの要素のダミーであるrは浮動小数点型なので関数str()を使って文字列型に変換する。

  • 'r='+str(r):文字列型のr=と文字列型のstr(r)+で結合する。

  • dic['r='+str(r)]:辞書dicにキー・値のペアを作成する。

    • キー:'r='+str(r)

    • 値:calculate_futre_value(100, r, 30)の返り値

最初の5行を表示する。

df_future.head()
r=0.01 r=0.03 r=0.06
0 100.000000 100.000000 100.000000
1 101.000000 103.000000 106.000000
2 102.010000 106.090000 112.360000
3 103.030100 109.272700 119.101600
4 104.060401 112.550881 126.247696

最後の5行を表示する。

df_future.tail()
r=0.01 r=0.03 r=0.06
26 129.525631 215.659127 454.938296
27 130.820888 222.128901 482.234594
28 132.129097 228.792768 511.168670
29 133.450388 235.656551 541.838790
30 134.784892 242.726247 574.349117
df_future.plot()
pass
_images/356bdf9a517f0d7cd5c1c288e16dd6eabf72af13aa6bae7c2d37c038f662abd6.png

その他のプロット#

種類#

2つの書き方が準備されている。

  1. 書き方1:

    .plot.xxxx()
    

    ここでxxxxは、プロットの種類を表す。

  2. 書き方2:

    .plot.(kind='xxxx')
    

    ここでkindはプロットの種類を指定する引数であり,'xxxx'は文字列。

この2つの方法は同じプロットを表示することなる。 まず,各プロットについての箇条書きでまとめた後,実際にデータを使いプロットについて説明することにする。

  • ライン・プロット

    • 上で説明した直線・曲線のプロット。

    • 書き方1:.plot.line()

    • 書き方2:.plot()であり,引数kind='line'ははデフォルトの値。

    • プロットの例

  • 散布図(DataFrameのみ)

  • ヒストグラム(連続変数に使う)

    • 書き方1:.plot.hist()

    • 書き方2:.plot(kind='hist')

    • histはHISTogramのHIST

    • プロットの例

  • カーネル密度推定プロット

    • 書き方1:.plot.kde()もしくは.plot.density()

    • 書き方2:.plot(kind='kde')もしくは.plot(kind='density')

    • kdeはKernel Density EstimateのKDE

    • プロットの例

  • 縦向きの棒グラフ(カテゴリーなどの離散変数に使う)

  • 横向き棒グラフ(カテゴリーなどの離散変数に使う)

    • 書き方1:.plot.barh()

    • 書き方2:.plot(kind='barh')

    • barhhはHorizontalのH

    • プロットの例

  • ボックスプロット

  • エリア・プロット

  • パイチャート

  • 六角形プロット(DataFrameのみ)

上で説明したライン・プロットの引数は他のプロットと共通のものが多いが,それぞれ独自の引数もある。

以下では散布図,ヒストグラム,カーネル密度推定プロット,棒グラフについて説明する。 加えて,縦線と横線を表示する方法も紹介する。

説明には次のコードで生成するDataFrameを使う。列XYには標準正規分布(平均0,標準偏差1)から生成した100個のランダム変数が含まれている。Zには正規分布(平均2,標準偏差1)から抽出した100個のランダム変数が格納されている。

rng = np.random.default_rng()
df1 = pd.DataFrame({'X':rng.normal(size=100),
                    'Y':rng.normal(size=100),
                    'Z':rng.normal(loc=2, size=100)})

XYは同じ標準正規分布から生成されているが,異なる値から構成されている。

散布図#

散布図をプロットする場合は次の構文となる。

<書き方1>
df1.plot.scatter(x='列ラベル', y='列ラベル')

<書き方2>
df1.plot(x='列ラベル', y='列ラベル', kind='scatter')
  • x:横軸に使う列ラベル(文字列)

  • y:縦軸に使う列ラベル(文字列)

XYを使ってプロットしてみよう。

df1.plot.scatter(x='X', y='Y')
pass
_images/ad10b4b73a69c79d2f44454a9d071466215f433b4c62828e28d66850cad13559.png

<基本的な引数>

様々な引数があり図に「飾り付け」をすることができる。詳しくはこのリンクを参照することにして,ここでは基本的な引数だけを紹介する。

  • title:図のタイトル(文字列型で指定)

  • color:色(リストにして列の順番で指定する; 参照サイト

    • rは赤

    • kは黒

    • gはグリーン

  • marker:観測値のマーカー(o.>^などがある; 参照サイト

  • s:マーカーの大きさ(markersizeではない!)

  • fontsize:横軸・縦軸の数字のフォントサイズの設定

  • figsize:図の大きさ

    • figsize=(キャンバスの横幅、キャンバスの縦の長さ)

  • legend:凡例の表示を指定

    • DataFrameの場合はデフォルトはTrue

    • Seriesの場合はデフォルトはFalse

  • label:凡例の表現を指定(Seriesのみ有効)

  • grid:グリッド表示(ブール型;デフォルトはFalse)

  • ax:プロットする「軸」を指定する。

df1.plot.scatter(x='X', y='Y',
                 title='タイトルです',
                 color='red',
                 marker='^',
                 s=100,
                 fontsize=20,
                 figsize=(8,4),
                 # legend=False,
                 label='Yの判例',
                 grid=True
                )
pass
_images/535664602e2a52fc7947c6c6a66d8102ca8f5148e5dee99b4cc5862785f6db5c.png

この図ではタイトルと横軸・縦軸ラベルの大きさが調整できていないが,上で説明したタイトルとラベルのサイズの調整のコードと共通なので,そちらを参照しよう。

またライン・プロットと同じように引数axを使うことにより,複数の散布図を重ねてプロットできる。次のコードはXY,そしてXZの散布図を同じ「軸」に表示している。

ax_ = df1.plot.scatter(x='X', y='Y', label='Yのデータ')
df1.plot.scatter(x='X', y='Z',
         color='red', marker='^', label='Zのデータ', ax=ax_)
pass
_images/bbb0040511d6322ae8e300279183b1d5fa4fd4167feca15d2c1cc5f091f925a7.png

ヒストグラム#

ヒストグラムは次の構文となる。

<書き方1>
df1.plot.hist(y='列ラベル')

<書き方2>
df1.plot(y='列ラベル', kind='hist')
  • y:縦軸に使う列ラベル(文字列、複数指定する場合はリスト)

  • 横軸は自動で設定されるためxは指定する必要はない

df1.plot.hist(y='Y')
pass
_images/aced103c810cb218389c34c1ba6e8e7ccb22ba0327fdf5daa6a38ea514ced4b4.png

<基本的な引数>

様々な引数があり図に「飾り付け」をすることができる。詳しくはこのリンクを参照することにして,ここでは基本的な引数だけを紹介する。

  • title:図のタイトル(文字列型で指定)

  • bins:柱の数

  • color:色(リストにして列の順番で指定する; 参照サイト

    • rは赤

    • kは黒

    • gはグリーン

  • edgecolor又はec:柱の境界線の色

  • alpha:透明度(0から1.0; デフォルトは1

  • density:縦軸を相対度数にする(デフォルトはFalse

    • 全ての柱の面積の合計が1になるように縦軸が調整される。1つの柱の高さが1よりも大きくなる場合もある。

  • fontsize:横軸・縦軸の数字のフォントサイズの設定

  • figsize:図の大きさ

    • figsize=(キャンバスの横幅、キャンバスの縦の長さ)

  • legend:凡例の表示を指定

    • DataFrameの場合はデフォルトはTrue

    • Seriesの場合はデフォルトはFalse

  • label:凡例の表現を指定(Seriesのみ有効)

  • grid:グリッド表示(ブール型;デフォルトはFalse)

  • subplots:複数の図をプロットする(詳細はライン・プロットを参照)

  • ax:プロットする「軸」を指定する。

引数を指定してXのヒストグラムをプロットしてみよう。

df1.plot.hist(y='Y',
              bins=20,
              title='タイトルです',
              color='red',
              ec='white',
              alpha=0.5,
              density=True,
              fontsize=20,
              figsize=(8,4),
              legend=True,
              label='Xの凡例',
              grid=True
             )
pass
_images/5b7884e03502368932f2458f3da44a1ac3fed596da5d931766f67b7b016be72b.png

この図ではタイトルと横軸・縦軸ラベルの大きさが調整できていないが,上で説明したタイトルとラベルのサイズの調整のコードと共通なのでそちらを参照しよう。

次に複数のデータを重ねてプロットする場合を考えよう。ここで役に立つ引数がalphaである。

df1.plot.hist(y=['Y','Z'],
              bins=30,
              color=['r','k'],
              edgecolor='k',
              alpha=0.4)
pass
_images/29bcc6344f6e4e46a3d9d70359a3d7f37049f5969f4b5154da5668fdf7b62595.png

濃い部分が重なっている部分となる。また柱を積み上げて表示するにはstacked=True(デフォルトはFalse)を使う。

df1.plot.hist(y=['Y','Z'],
              bins=30,
              color=['r','k'],
              edgecolor='white',
              stacked=True)
pass
_images/7bbb7e678a1d7669a1c964b35300774693d538b8ea558f5b7ef52395834503a1.png

赤の上に黒が積み上げられている。

カーネル密度推定プロット#

ヒストグラムは縦軸に度数,横軸に階級を取ったグラフだが,関連する手法にカーネル密度推定と呼ばれるものがある。考え方は簡単で,上のようなヒストグラムのデータに基づき面積が1になるようにスムーズな分布を推定する手法である。ヒストグラムとカーネル密度関数を重ねてプロットすることもできる。

次の構文となる。

<書き方1>
df1.plot.kde(y='列ラベル')

<書き方2>
df1.plot(y='列ラベル', kind='kde')
  • y:縦軸に使う列ラベル(文字列、複数指定する場合はリスト)

  • 横軸は自動で設定されるためxは指定する必要はない

この場合,df1にある全ての列がヒストグラムとして重ねて表示される。特定の列だけを使う場合は列を選択してplot()を使う。

df1.plot.kde(y=['X','Z'])
pass
_images/97629ff35c8a002da4fc70921331cb22437dd45e260b1354e2edf40b062aaee6.png

<基本的な引数>

様々な引数があり図に「飾り付け」をすることができる。詳しくはこのリンクを参照することにして,ここでは基本的な引数だけを紹介する。

  • title:図のタイトル(文字列型で指定)

  • linestyle又はstyle:線のスタイル(リストにして列の順番で指定する;----.:

  • linewidth or lw:線の幅

  • color:色(リストにして列の順番で指定する; 参照サイト

    • rは赤

    • kは黒

    • gはグリーン

  • alpha:透明度(0から1.0; デフォルトは1

  • fontsize:横軸・縦軸の数字のフォントサイズの設定

  • figsize:図の大きさ

    • figsize=(キャンバスの横幅、キャンバスの縦の長さ)

  • legend:凡例の表示を指定

    • DataFrameの場合はデフォルトはTrue

    • Seriesの場合はデフォルトはFalse

  • label:凡例の表現を指定(Seriesのみ有効)

  • grid:グリッド表示(ブール型;デフォルトはFalse)

  • ax:プロットする「軸」を指定する。

引数を指定してXをプロットしてみる。

df1.plot.kde(y='X',
             title='タイトルです',
             linewidth=5,
             linestyle='-.',
             color='red',
             alpha=0.5,
             fontsize=20,
             figsize=(8,4),
             legend=True,
             label='Xの凡例',
             grid=True
            )
pass
_images/5f14342c86b3ab4b20b6c31d1fc9c9dcc68d04bc94ca6ba8490c39752015c3ab.png

この図ではタイトルと横軸・縦軸ラベルの大きさが調整できていないが,上で説明したタイトルとラベルのサイズの調整のコードと共通なのでそちらを参照しよう。

次にヒストグラムとカーネル密度推定プロットを重ねて図示してみる。ここで重要な点がヒストグラムに引数density=Trueを設定することである。これがないと縦軸の単位が異なり上手く表示できない。

ax_ = df1.plot.hist(y='X',
                    label='Xのヒストグラム',
                    density=True)
df1.plot.kde(y='X',
             label='XのKDE',
             ax=ax_)
ax_.legend()
pass
_images/a469ed92da46dca9e39f81b584274227e97a0df08b8ebe57f7272f7e20f69df6.png

縦線・横線#

図に縦線や横線を追加したい場合がある。その場合は,タイトルとラベルのサイズの調整にあるように「軸」に追加していく事になる。次のような書き方となる。

  • 縦線の場合

    ax_.axvline(<横軸の値>)
    

    ここで`axvline`の`ax`はAXis,`v`はVertical,`line`はLINEのことを表している。
  • 横線の場合

    ax_.axhline(<縦軸の値>)
    

    ここで`axhline`の`ax`はAXis,`h`はHorizontal,`line`はLINEのことを表している。

ここでax_.plot()で返された「軸」のことである。

Yのヒストグラムを使ってプロットしてみよう。

ax_ = df1.plot.hist(y='Y', alpha=0.1)
ax_.axvline(0)
ax_.axhline(10)
pass
_images/730330f9bdac6cc48cd910f2d1e3d6b87f78aeab750c9616922ec762a2e30a92.png

<基本的な引数>

様々な引数があり図に「飾り付け」をすることができる。詳しくはこのリンクこのリンクを参照することにして,ここでは基本的な引数だけを紹介する。

  • yminaxvlineの縦軸における最小値(0~1の値; デフォルト0

  • ymaxaxvlineの縦軸における最大値(0~1の値; デフォルト1

  • xminaxhlineの横軸における最小値(0~1の値; デフォルト0

  • xmaxaxhlineの横軸における最大値(0~1の値; デフォルト1

  • linestyle:線のスタイル(リストにして列の順番で指定する;- -- -. :

  • linewidth or lw:線の幅

  • color:色(リストにして列の順番で指定する; 参照サイト

    • rは赤

    • kは黒

    • gはグリーン

  • alpha:透明度(0から1.0; デフォルトは1

引数を指定してプロットしてみる。

ax_ = df1.plot.hist(y='Y', alpha=0.1)
ax_.axvline(0,
            ymin=0.3,
            ymax=0.95,
            linestyle=':',
            linewidth=5,
            color='g',
            alpha=0.8)
ax_.axhline(10,
            xmin=0.05,
            xmax=0.7,
            linestyle='-.',
            linewidth=3,
            color='k',
            alpha=0.5)
pass
_images/0691bafba3485c7f36daefee9599dad458c0f55e73b6cce273a2f9d8b63b5ba3.png

最後に上のヒストグラムとカーネル密度推定プロットに縦線を加えてみよう。

ax_ = df1.plot.hist(y='X',
                    label='Xのヒストグラム',
                    density=True)
df1.plot.kde(y='X',
             label='XのKDE',
             ax=ax_)
ax_.legend()
ax_.axvline(0, color='red')
pass
_images/518e5a14d4797a50b2ef6c70998a445e0f019440738b0bf52fbcf1d109dee9e3.png

棒グラフ#

まず次のコードでデータを準備しよう。

df2 = pd.DataFrame({'country':['A','B','C'],
                    'gdp':[100,90,110],
                    'con':[50,60,55],
                    'inv':[15,10,20],
                    'gov':[10,5,30],
                    'netex':[25,15,5]})

3国のGDPとその構成要素からなるDataFrameである。

  • country:国

  • gdp:GDP

  • con:消費

  • inv:投資

  • gov:政府支出

  • netex:純輸出

このDataFrameを使って棒グラフの作成方法を説明するが,次の構文となる。

<書き方1>
df2.plot.bar(x='列ラベル', y='列ラベル')

<書き方2>
df2.plot(x='列ラベル', y='列ラベル', kind='bar')
  • x:横軸に使う列ラベル(文字列)

  • y:縦軸に使う列ラベル(文字列、複数の場合はリスト)

まずA国のgdpの棒グラフを表示してみよう。

df2.plot.bar(x='country', y='gdp')
pass
_images/26cadd3667616a814ab301a99b2489f63ba5a7283f33331ac404d8b416c511ca.png

複数の棒(データ)を並べたい場合もあるだろう。その場合は引数yにリストを指定すれば表示できる。

df2.plot.bar(x='country', y=['gdp','con'])
pass
_images/3af62c3ec5a4340a67cacd1b85f4435b5d3b4bea150dab94d54acf3f19f73952.png

<基本的な引数>

詳しい引数についての説明はこのリンクを参照することにして,ここでは基本的な引数だけを紹介する。

  • color:色(リストにして列の順番で指定する; 参照サイト

    • r又はred:赤

    • k又はblack:黒

    • g又はgreen:グリーン

  • stacked:(ブール型;デフォルトはFalse)

    • 複数データを使う場合に棒を積み上げるかどうかを指定

  • fontsize:横軸・縦軸の数字のフォントサイズの設定

  • figsize:図の大きさ

    • figsize=(キャンバスの横幅、キャンバスの縦の長さ)

  • legend:凡例の表示を指定

    • DataFrameの場合はデフォルトはTrue

  • label:凡例の表現を指定

  • grid:グリッド表示(ブール型;デフォルトはFalse)

  • rot(rotationの略):横軸の変数の表示の角度(デフォルトは90

  • subplots:複数の図をプロットする(詳細はライン・プロットを参照)

  • ax:プロットする「軸」を指定する。

これらの引数を使いプロットしてみよう。

df2.plot.bar(x='country', y=['con','inv','gov','netex'],
             color=['red','black','green','orange'],
             stacked=True,
             fontsize=20,
             figsize=(8,4),
             # legend=False,       
             label=['消費','投資','政府支出','純輸出'],
             grid=True,
             rot=0
            )
pass
_images/f5988ac2beed3f795295bc6ce6bae03e5cc4c0fc8917e2db180a3aa12f9711b6.png

次に,ライン・プロットを追加する例を考えてみよう。df2には列gdpがあり,それを表すライン・プロットを重ねることにしよう。

ax_ = df2.plot.bar(x='country', y=['con','inv','gov','netex'],
                   stacked=True,
                   fontsize=15,
                   label=['消費','投資','政府支出','純輸出'],
                   rot=0)

df2.plot(x='country', y='gdp',
         color='black',
         marker='o',
         legend=True,
         label='国内総生産',
         ax=ax_)

ax_.set_title('3カ国のGDPと構成要素', size=20)
ax_.set_xlabel('国', size=15)
ax_.set_ylabel('単位:億米ドル', size=15)
pass
_images/976cfca80ff50a272148142b25a3107f3629d6b86b528e139901570486de7b54.png

棒の高さとGDPのマーカーの高さは同じであることがわかる。