データ分析系プログラマーのブログ

主にPythonを使ったデータ分析や機械学習をやっています。

matplotlibの基本的な使い方その6

matplotlibで使えるグラフとして、円グラフがあります。円グラフはデータの割合を見たい時などに使用します。円グラフを使用すると、データ全体のうち、ある項目が全体のうちどのくらいの割合であるのかを視覚的に確認できます。この記事では、matplotlibによる円グラフの描き方について紹介しています。

必要なライブラリをインポートする

今回は、matplotlibの他に、numpyとpandasもインポートしておきます。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

ランダムな整数を生成する

ここでは、円グラフを描画するために、0から4までの5つの整数を500個生成しています。

df = pd.DataFrame(data = np.random.randint(0, 5, 500), columns = ['data'])
df.head()
data
0 4
1 0
2 4
3 0
4 2

生成した整数を集計する

先ほど生成した0から1までの整数をvalue_countsで集計しています。

df['data'].value_counts()

1 109
0 104
2 103
3 94
4 90
Name: data, dtype: int64

円グラフを描画する

円グラフは、pieで描画することができます。引数には、labelsを指定しています。

plt.figure(figsize = (10,10))
plt.pie(df['data'].value_counts(), labels = df['data'].value_counts().index)
plt.show()

f:id:hira03:20200716110336p:plain
matplotlib06_pie01

見た目を整える

円グラフの引数には、幾つかの引数があるので、それらを指定することで見た目を整えることができます。ここでは、labelsでラベル表示して、autopctで値を割合表示にしています。また、startangleで、90度回転し、counterclockで時計回りで値を表示しています。textpropsでは、文字サイズを指定しています。

plt.figure(figsize = (10,10))

textprops = {'fontsize' : 20}


plt.pie(df['data'].value_counts(), 
        labels = df['data'].value_counts().index,
       autopct = '%.1f%%',
       startangle = 90,
       counterclock = False,
       textprops = textprops)

plt.show()

f:id:hira03:20200716110359p:plain
matplotlib06_pie02

実際のデータで円グラフを描画する

ここでは、実際のデータを使って円グラフを描いています。使用するデータは、アメリカの歳入、歳出と、日本の歳入、歳出です。アメリカの歳入と歳出は、外務省が公表しているアメリカ合衆国、2021年度予算教書の値を参考にしています。また、日本の歳入と歳出は、財務省が公表している、平成30年度 歳入・歳出の概要の値を参考にしています。

us_revenue = [
["個人所得税",18120],
["法人税",2640],
["社会保障等",13120],
["その他",3190]
]

df1 = pd.DataFrame(us_revenue, columns=["項目","金額"])
df1.head()
項目 金額
0 個人所得税 18120
1 法人税 2640
2 社会保障 13120
3 その他 3190
us_expenditure = [
["国防関係費",7130],
["非国防関係費",7240],
["社会保険",10920],
["メディケア",6940],
["メディケイド",4470],
["利払費",3760],
["その他",7440]
]

df2 = pd.DataFrame(us_expenditure, columns=["項目","金額"])
df2.head()
項目 金額
0 国防関係費 7130
1 非国防関係費 7240
2 社会保険 10920
3 メディケア 6940
4 メディケイド 4470
jp_revenue = [
["租税及印紙収入",59928000],
["官業益金及官業収入",45702],
["政府資産整理収入",299639],
["雑収入",4676408],
["公債金",35395400],
["前年度剰余金受入",1012910]
]

df3 = pd.DataFrame(jp_revenue, columns=["項目","金額"])
df3.head()
項目 金額
0 租税及印紙収入 59928000
1 官業益金及官業収入 45702
2 政府資産整理収入 299639
3 雑収入 4676408
4 公債金 35395400
jp_expenditure = [
["社会保障関係費",33221146],
["文教及び科学振興費",6089961],
["国債費",22741322,],
["恩給関係費",249984],
["地方交付税交付金",15871381],
["地方特例交付金",154400],
["防衛関係費",5869979],
["公共事業関係費",10247180],
["その他",11209720]
]

df4 = pd.DataFrame(jp_expenditure, columns=["項目","金額"])
df4.head()
項目 金額
0 社会保障関係費 33221146
1 文教及び科学振興費 6089961
2 国債 22741322
3 恩給関係費 249984
4 地方交付税交付金 15871381
fig, axes = plt.subplots(2,2, figsize = (16,12))

textprops = {'fontsize' : 14}

axes[0][0].pie(df1['金額'], 
        labels = df1['項目'],
       autopct = '%.1f%%',
       startangle = 90,
       counterclock = False,
       textprops = textprops,
        labeldistance=0.9)

axes[0][1].pie(df2['金額'], 
        labels = df2['項目'],
       autopct = '%.1f%%',
       startangle = 90,
       counterclock = False,
       textprops = textprops,
        labeldistance=0.9)

axes[1][0].pie(df3['金額'], 
        labels = df3['項目'],
       autopct = '%.1f%%',
       startangle = 90,
       counterclock = False,
       textprops = textprops,
        labeldistance=0.9)

axes[1][1].pie(df4['金額'], 
        labels = df4['項目'],
        autopct = '%.1f%%',
        startangle = 90,
        counterclock = False,
        textprops = textprops,
        labeldistance=0.9)

axes[0][0].set_title("アメリカの歳入(2020年度)",fontsize = 16) 
axes[0][1].set_title("アメリカの歳出(2020年度)",fontsize = 16) 
axes[1][0].set_title("日本の歳入(平成30年度)",fontsize = 16) 
axes[1][1].set_title("日本の歳出(平成30年度)",fontsize = 16) 

axes[0][0].axis('equal')
axes[0][1].axis('equal')
axes[1][0].axis('equal')
axes[1][1].axis('equal')

plt.show()

f:id:hira03:20200716110440p:plain
matplotlib06_pie03

matplotlibの基本的な使い方その5

matplotlibで使えるグラフとして、ヒストグラムがあります。ヒストグラムはデータの分布具合を見たい時などに使用します。ヒストグラムを使用すると、データ全体のうち、その階級にデータが多くあるのかなどを視覚的に確認できます。この記事では、matplotlibによるヒストグラムの描き方について紹介しています。

必要なライブラリをインポートする

今回は、matplotlibの他に、numpyとpandasもインポートしておきます。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

標準正規分布に従った乱数を生成

今回は、ヒストグラムの描画のために、numpyのnp.random.normalを使用して標準正規分布に従った乱数を生成します。以下のように、平均、標準偏差、サンプルサイズを引数として指定することで標準正規分布に従った乱数を生成することができます。

# 平均 1
mu = 0
# 標準偏差
sigma = 1
#  戻り値のサイズ
size = 1000
np.random.seed(0)

df = pd.DataFrame(data = np.random.normal(mu , sigma, size), columns = ['normal'])
df.head()
normal
0 1.764052
1 0.400157
2 0.978738
3 2.240893
4 1.867558

ヒストグラムを描画

ヒストグラムは、histで描画することができます。

plt.figure(figsize = (12,8))
plt.hist(df['normal'])
plt.show()

f:id:hira03:20200715112219p:plain
matplotlib05_hist01

見た目を整える

ヒストグラムの引数では、棒の数(bin)、棒のサイズ(rwidth)、色の指定などを指定できます。ここでは、棒の数(階級数)を20、棒のサイズを0.8、色をskyblueにしています。

plt.figure(figsize = (12,8))
plt.hist(df['normal'], bins = 20, rwidth = 0.8 ,color = 'skyblue')
plt.show()

f:id:hira03:20200715112251p:plain
matplotlib05_hist02

正規分布曲線を描く

正規分布の曲線を描く方法は幾つかありますが、ここでは、scipy.statsを使用した方法で描いています。linspaceを使って、0.01から0.99までの値で100個の正規分布に従った乱数を生成しています。曲線はplotで描いています。plotは厳密には直線ですが、100この細かい線の集まりによって曲線になります。それと、先ほど描いたヒストグラフを重ねて描画しています。

from scipy.stats import norm

fig, ax = plt.subplots(1, 1, figsize = (12, 8))

x = np.linspace(norm.ppf(0.01), norm.ppf(0.99), 100)
# 折れ線グラフを描画
ax.plot(x, norm.pdf(x),'r-', lw=2, label='norm pdf')

# ヒストグラムを描画
ax.hist(df['normal'],  bins = 20, rwidth = 0.8 ,color = 'skyblue',  density=True)
ax.legend(loc='best', frameon=False)
plt.show()

f:id:hira03:20200715112317p:plain
matplotlib05_hist03

matplotlibの基本的な使い方その4

matplotlibで使えるグラフとして、棒グラフがあります。棒グラフは、折れ線グラフ同様に、データの推移をみたりする場合に使用する以外にも、データを比較したりする場合にも使用します。この記事では、matplotlibによる棒グラフの描き方について紹介しています。

必要なライブラリをインポートする

今回は、matplotlibの他に、numpyとpandasもインポートしておきます。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

分析データを用意する

ここでは、POSデータのようなお店での商品の売り上げた時の記録データを想定したデータで棒グラフを描いてみます。以下のデータは、KSP-POSで公開されている、オープンデータの一部を使用して、月ごとの商品の売り上げ個数を集計したものを想定した架空のデータです。

data1 = [
[4549660503637,"バンダイ","バンダイ 鬼滅の刃ウエハース2 1枚","05月01日",594,50],
[4549660503637,"バンダイ","バンダイ 鬼滅の刃ウエハース2 1枚","06月01日",594,50],
[4549660503637,"バンダイ","バンダイ 鬼滅の刃ウエハース2 1枚","07月01日",594,100],
[4901581249603,"木村屋総本店","木村屋 北海道れん乳ツイストドーナツ 3本","05月01日",417,300],
[4901581249603,"木村屋総本店","木村屋 北海道れん乳ツイストドーナツ 3本","06月01日",417,100],
[4901581249603,"木村屋総本店","木村屋 北海道れん乳ツイストドーナツ 3本","07月01日",417,200],
[4901820427229,"敷島製パン","パスコ 生なごやん 1個","05月01日",301,200],
[4901820427229,"敷島製パン","パスコ 生なごやん 1個","06月01日",301,100],
[4901820427229,"敷島製パン","パスコ 生なごやん 1個","07月01日",301,50]
         ]

df1 = pd.DataFrame(data1, columns=["JANCD","メーカー名","商品名称","月日","金額PI","売れた数"])
df1.head()
JANCD メーカー名 商品名称 月日 金額PI 売れた数
0 4549660503637 バンダイ バンダイ 鬼滅の刃ウエハース2 1枚 05月01日 594 50
1 4549660503637 バンダイ バンダイ 鬼滅の刃ウエハース2 1枚 06月01日 594 50
2 4549660503637 バンダイ バンダイ 鬼滅の刃ウエハース2 1枚 07月01日 594 100
3 4901581249603 木村屋総本店 木村屋 北海道れん乳ツイストドーナツ 3本 05月01日 417 300
4 4901581249603 木村屋総本店 木村屋 北海道れん乳ツイストドーナツ 3本 06月01日 417 100

棒グラフを描画する

棒グラフは、barで描画することができます。ここでは、groupbyを使用して、メーカーごとの売れた数の合計を棒グラフにしています。

plt.figure(figsize = (12,8))
plt.bar(df1['メーカー名'].value_counts().index, df1.groupby('メーカー名').sum()['売れた数'])
plt.show()

f:id:hira03:20200714113030p:plain
matplotlib04_bar01

複数の棒グラフを描画する

以下の例は、大手通信会社3社の2016年から2020年までの5期分の売上高です。これらのデータは、edinetで公開されている有価証券報告書より調べることができます。複数の棒グラフを描く場合は、インスタンス化する描画方法で、必要な分だけbarで描くことができます。

data2 = [
[4461505,4588579,4807129,4900345,4639078],
[4466135,4748259,5041978,5080353,5237221],
[3410595,3483056,3582635,4656815,4861247]
]

df2 = pd.DataFrame(data2, index = ['NTT','KDDI','SOFTBANK'],
                 columns = ["2016年3月","2017年3月","2018年3月","2019年3月","2020年3月"])
df2 = df2.T
df2.head()
NTT KDDI SOFTBANK
2016年3月 4461505 4466135 3410595
2017年3月 4588579 4748259 3483056
2018年3月 4807129 5041978 3582635
2019年3月 4900345 5080353 4656815
2020年3月 4639078 5237221 4861247
plt.figure(figsize = (12,8))
x = np.arange(len(df2))
bar_width = 0.4

plt.bar(x, df2['NTT'], color = 'red', width = bar_width, label= 'NTT')
plt.bar(x + bar_width, df2['KDDI'], color = 'blue', width = bar_width, label= 'KDDI')

plt.xticks(x + bar_width / 2, df2.index, fontsize = 20)
plt.legend()
plt.show()

f:id:hira03:20200714113107p:plain
matplotlib04_bar02

for文を使ってまとめて棒グラフを描する

描画したブラフがたくさんある場合は、for文を使ってまとめて描画処理を行うこともできます。

plt.figure(figsize = (16,8))

x = np.arange(len(df2), dtype = 'float64')

bar_width = 0.1

for col in df2.columns:
    plt.bar(x, df2[col], width = bar_width, label= col)
    x += bar_width

plt.xticks((np.arange(len(df2)) + x - bar_width) / 2, df2.index, fontsize = 20)
plt.legend()
plt.show()

f:id:hira03:20200714113132p:plain
matplotlib04_bar03

matplotlibの基本的な使い方その3

matplotlibでは、様々はグラフを描画することができます。そのうちよく使うグラフとして散布図があります。散布図は、xとyの相関性を見るときなどに使用します。例えば、体重と身長、湿度と気圧、タクシーの乗車料金と移動距離と言った、相関性がありそうな2つのデータの関係を見るときなどに使用します。

必要なライブラリをインポートする

今回は、matplotlibの他に、pandasもインポートしておきます。

import pandas as pd
import matplotlib.pyplot as plt

分析データを用意する

今回使用するデータは、総務省統計局が公表している社会生活統計指標-都道府県の指標-2020という統計データのうち、2018年の日照時間(年間)と降水量(年間)のデータを使用しています。データは、都道府県ごとのデータとなっていて、各47個のデータとなっています。まず、リストで以下のように多次元配列としてデータを用意して、pandasのデータフレームにしておきます。

data = [
[1741.6,1642.0,1778.1,1998.4,1526.2,1765.0,1915.7,2199.1,2156.3,2381.3,
2308.3,2120.2,2112.2,2194.6,1698.8,1799.5,1880.7,1844.4,2391.3,2121.9,
2277.8,2208.7,2330.6,2325.9,2060.4,1981.8,2265.6,2247.5,2065.2,2288.8,
1825.7,1851.1,2229.2,2181.5,2025.0,2289.9,2248.1,2172.2,2265.0,2094.8,
2133.7,1994.4,2089.9,2143.3,2191.9,2051.2,1876.5],

[1282.0,1553.0,1322.0,1082.0,2016.5,1124.0,828.0,1282.5,1257.0,1046.5,
1056.0,1261.0,1445.5,1573.5,1795.5,2751.0,2765.5,2632.0,1153.5,886.0,
2087.0,2442.0,1695.5,1720.0,1863.0,1770.0,1651.5,2037.5,1646.5,1950.5,
2183.5,1976.5,1410.0,1878.5,1939.5,1760.0,1575.0,1796.5,3092.5,1617.0,
1877.0,1821.0,1950.5,1663.0,3167.5,2397.0,2469.5]
            ]

df = pd.DataFrame(data, index=['日照時間(年間)2018','降水量(年間)2018'])
df = df.T
df.head()
日照時間(年間)2018 降水量(年間)2018
0 1741.6 1282.0
1 1642.0 1553.0
2 1778.1 1322.0
3 1998.4 1082.0
4 1526.2 2016.5

散布図を表示する

以下では、scatterで散布図を描画しています。引数に、日照時間と降水量のデータを指定することで散布図を描画することができます。

plt.figure(figsize = (12,8))
plt.scatter(df['日照時間(年間)2018'], df['降水量(年間)2018'])
plt.show()

f:id:hira03:20200709113245p:plain
matplotlib03_scatter01

点の大きさ・色・スタイルを変更する

ここでは、先ほど描画した散布図をもう少しわかりやすく調整しています。scatterの引数として、ドットのサイズ、ドットの色、ドットの形状、透明度なども指定することができます。また、グラフにはタイトルとラベルも表示しています。

plt.figure(figsize = (12,8))

plt.scatter(df['日照時間(年間)2018'], df['降水量(年間)2018'], s = 200, c = 'deepskyblue', marker = '^', alpha = 0.5)

plt.title("日照時間と降水量の散布図", fontsize = 20)
plt.xlabel('日照時間 2018', fontsize = 15)
plt.ylabel('降水量 2018', fontsize = 15)

plt.show()

f:id:hira03:20200709113307p:plain
matplotlib03_scatter02

点の大きさや色をデータによって変える

先ほどの散布図をよりわかりやすくするために、ここではデータによってドットの大きさや色を変えてみます。やり方としては、日照時間のデータを割合にしたデータをカテゴリカルなデータとして、そのデータに応じて、大きさや色を変えていきたいと思います。なので、最初に、このデータの各種統計量をdescribeで確認してみます。すると、日照時間の最大値は2391.3であることがわかります。

df.describe()
日照時間(年間)2018 降水量(年間)2018
count 47.000000 47.000000
mean 2070.027660 1777.680851
std 211.684502 549.867745
min 1526.200000 828.000000
25% 1898.200000 1366.000000
50% 2120.200000 1760.000000
75% 2238.350000 1996.500000
max 2391.300000 3167.500000

カテゴリカルなデータを生成する

日照時間の最大値がわかったので、この値を使ってカテゴリカルなデータを生成してみます。ここでは一つ関数を用意しています。これは、先ほどの日照時間の最大値で割ることで値を割合に変えて、さらに100倍して、その値の小数点をroundで丸めています。関数を適用すると、datasizeという新しい特徴量が生成されていることがわかります。

maxdata = df.max()

def category(x):
    return (x/maxdata[0]*100).round()
df["datasize"] = df["日照時間(年間)2018"].apply(category)
df.head()
日照時間(年間)2018 降水量(年間)2018 datasize
0 1741.6 1282.0 73.0
1 1642.0 1553.0 69.0
2 1778.1 1322.0 74.0
3 1998.4 1082.0 84.0
4 1526.2 2016.5 64.0

大きさや色を変えた散布図

先ほど生成したカテゴリカルなデータを使って、あらためて散布図を描画してみます。色やサイズはdatasizeの値を使うことでデータごとに大きさや色が変わります。また、色は、cmapを使うことで値によってグラデーション的に色が変わります。ここでは、cmapのうち、plasmaというのを使用しています。colorbarというのを表示しておくと、よりどの値が何色なのかがわかりやすくなります。

plt.figure(figsize = (12,8))

plt.scatter(df['日照時間(年間)2018'], df['降水量(年間)2018'], s = df['datasize']*10, c = df['datasize'], cmap = 'plasma', alpha = 0.8)
plt.colorbar()

plt.title("日照時間と降水量の散布図", fontsize = 20)
plt.xlabel('日照時間 2018', fontsize = 15)
plt.ylabel('降水量 2018', fontsize = 15)

plt.show()

f:id:hira03:20200709113345p:plain
matplotlib03_scatter03

matplotlibの基本的な使い方その2

matplotlibでは、様々はグラフを描画することができます。そのうちよく使うグラフとして折れ線グラフがあります。折れ線グラフは株価や人口増加の推移など、主に時系列のデータを扱うときに使用します。この記事では、株価のデータを使って折れ線グラフの基本的な描き方について紹介しています。

株価のデータを取得する

ここでは、株価のデータを折れ線グラフで描画したいので、まずは、pandas_datareaderを使って、株価のデータをpandasのデータフレームとして取得してきます。取得先は、Stooqというポーランドにあるサイトで提供されている株価のデータを取得しています。証券コードなどを指定することで株価のデータを取得できます。ここではNTT(証券コード:9432)とKDDI証券コード:9433)の株価のデータを取得しています。

import numpy as np
import pandas as pd
import pandas_datareader.data as web
import matplotlib.pyplot as plt

df1 = web.DataReader('9432.JP', 'stooq')
df2 = web.DataReader('9433.JP', 'stooq')
df1.head()
Open High Low Close Volume
Date
2020-07-07 2490.5 2497.0 2473.5 2483.0 4458500
2020-07-06 2496.5 2522.0 2488.5 2520.0 3045500
2020-07-03 2481.0 2488.5 2469.5 2477.5 2723400
2020-07-02 2450.0 2480.5 2437.0 2473.5 5484000
2020-07-01 2495.0 2510.0 2454.5 2461.0 5370600
df2.head()
Open High Low Close Volume
Date
2020-07-07 3192.0 3228.0 3191.0 3224.0 3807500
2020-07-06 3210.0 3247.0 3199.0 3241.0 2609400
2020-07-03 3193.0 3201.0 3175.0 3192.0 1762500
2020-07-02 3196.0 3202.0 3163.0 3175.0 3741100
2020-07-01 3242.0 3253.0 3173.0 3187.0 4861700

折れ線グラフ

折れ線グラフは、plotで描くことができます。先ほど取得した株価のデータのうち、終値(Close)を折れ線グラフとして描画しています。

plt.figure(figsize = (12,8))
plt.plot(df1['Close'])
plt.show()

f:id:hira03:20200708112231p:plain
matplotlib02_plot01

複数のグラフを描画する

一つの画面に複数のグラフを描画したい場合は、以下のようにplotを2回描くことで、それぞれのグラフを重ねて描画することができます。以下の例は、NTTとKDDI終値をそれぞれ描画しています。

plt.figure(figsize = (12,8))
plt.plot(df1['Close'])
plt.plot(df2['Close'])
plt.show()

f:id:hira03:20200708112305p:plain
matplotlib02_plot02

タイトル・軸・凡例を設定する

先ほどまでのグラフだと何のグラフなのかがわからないということがあります。なので、グラフのタイトルや軸の名前、凡例などを設定する必要があります。以下のように、それぞれタイトル(title)、軸の名前(xlabelとylabel)、凡例(legend)をそれぞれ記述することで、グラフがよりわかりやすくなります。

plt.figure(figsize = (12,8))

plt.plot(df1['Close'])
plt.plot(df2['Close'])

plt.title("NTTとKDDIの株価の推移", fontsize = 20)
plt.xlabel('date', fontsize = 15)
plt.ylabel('price', fontsize = 15)

plt.legend(['NTT', 'KDDI'])

plt.show()

f:id:hira03:20200708112328p:plain
matplotlib02_plot03

線の色・太さ・スタイルを変更する

その他に、線の色や、太さ、スタイルなども変更することができます。これらは、plotの引数として指定できます。色を指定するときは、colorで、blueとかredと言ったワードで色をしていることもできますし、#2971e5と言ったカラーコードで指定することもできます。線の太さは、linewidthで設定することができます。特に指定しなければ1.0となっています。線のスタイルというのは、実線や点線などの線の種類をlinestyleで指定できます。実線はsolid、点線はdashedとなっています。

plt.figure(figsize = (12,8))

plt.plot(df1['Close'], color = 'blue', linewidth =3.0, linestyle = 'solid')
plt.plot(df2['Close'], color = 'red', linewidth =3.0, linestyle = 'dashed')

plt.title("NTTとKDDIの株価の推移", fontsize = 20)
plt.xlabel('date', fontsize = 15)
plt.ylabel('price', fontsize = 15)

plt.legend(['NTT', 'KDDI'])

plt.show()

f:id:hira03:20200708112347p:plain
matplotlib02_plot04

matplotlibの基本的な使い方その1

Pythonには、データ分析を行う上で便利なツールがあります。そのうちのひとつとしてmatplotlibがあります。matplotlibはグラフ描画ライブラリです。このmatplotlibを使用することで、様々なグラフを描画することができます。この記事では、このmatplotlibについて、基本的な描画方法について紹介しています。

matplotlibとは?

matplotlibは、グラフ描画ライブラリです。matplotlibは、折れ線グラフ、棒グラフ、円グラフ、ヒストグラム、散布図などデータ分析を行うときに必要となる様々なグラフ描画を行うことができます。matplotlibを使いこなすことによって、エクセルよりも自由度の高いグラフを描くことができます。

必要なライブラリをインポートする

matplotlibを使用するときは、numpyやpandasなど他のデータ分析を行う中で使用することになります。ここでは、matplotlibの基本的な描画方法を試すために、numpyを使って乱数を生成したデータを使って描画を行っていきます。

import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)

インスタンス化なしで描画する方法

matplotlibを使用するときは、通常は、FigureやAxesをインスタンス化してグラフなどを描画するのですが、もっと簡単な方法としてはpltを使うことでインスタンス化を行わずにグラフを描画することができます。その代わりあまり細かな設定はできません。

x = np.linspace(0,1,20)
y =  2 * x + 0.1 * np.random.randn(20)
plt.plot(x,y)
plt.show()

f:id:hira03:20200707114142p:plain
matplotlib01_01

一般的な描画方法

matplotlibの一般的な描画方法は、FigureやAxesをインスタンス化を生成して描画する方法となります。Figureはグラフを配置する領域を意味ます。一方のAxesは、グラフを描画する領域を意味します。Axesをインスタンス化するときは、add_subplotでインスタンス化します。ここでは(111)すなわち「1行1列の1つ目」の位置を指定しています。

x = np.linspace(0,1,20)
y =  2 * x + 0.1 * np.random.randn(20)

fig = plt.figure()
ax = fig.add_subplot(111)

ax.plot(x,y)
plt.show()

f:id:hira03:20200707114215p:plain
matplotlib01_02

複数のグラフを描画する

matplotlibは、一つのFigure(グラフを配置する領域)に複数のAxes(グラフを描画する領域)を配置することができます。 やり方としては、add_subplotのときに、引数として22とすることで2行2列とすることができます。例えば、add_subplot(221)とすると、2行2列目の1番目、この場合は左上に、グラフを配置することを意味することになります。以下の例では、異なる四つのグラフを2行2列で配置しています。

x_1 = np.linspace(0,1,20)
y_1 =  2 * x_1 + 0.1 * np.random.randn(20)

x_2 = np.linspace(0,1,40)
y_2 =  2 * x_2 + 0.1 * np.random.randn(40)

x_3 = np.linspace(0,1,400)
y_3 =  2 * x_3 + 0.1 * np.random.randn(400)

x_4 = np.linspace(0,1,800)
y_4 =  2 * x_4 + 0.1 * np.random.randn(800)
fig = plt.figure()

ax_1 = fig.add_subplot(221)
ax_2 = fig.add_subplot(222)
ax_3 = fig.add_subplot(223)
ax_4 = fig.add_subplot(224)

ax_1.plot(x_1,y_1)
ax_2.plot(x_2,y_2)
ax_3.plot(x_3,y_3)
ax_4.plot(x_4,y_4)

plt.show()

f:id:hira03:20200707114247p:plain
matplotlib01_03

グラフの大きさを変える

グラフの大きさを指定したいときは、Figureをインスタンス化するときに引数として指定します。大きさを指定する引数の書き方は、figsize = (12,8)といった形で記述します。この時のサイズ単位はインチとなっています。

fig = plt.figure(figsize = (12,8))

ax_1 = fig.add_subplot(221)
ax_2 = fig.add_subplot(222)
ax_3 = fig.add_subplot(223)
ax_4 = fig.add_subplot(224)

ax_1.plot(x_1,y_1)
ax_2.plot(x_2,y_2)
ax_3.plot(x_3,y_3)
ax_4.plot(x_4,y_4)

plt.show()

f:id:hira03:20200707114418p:plain
matplotlib01_04

インスタンス化なしの場合の大きさの変え方

インスタンス化をしないで描画する場合も、以下のように、plt.figure(figsize = (12,8))を1行追加することでグラフの大きさを指定することができます。

x = np.linspace(0,1,20)
y =  2 * x + 0.1 * np.random.randn(20)

plt.figure(figsize = (12,8))
plt.plot(x,y)
plt.show()

f:id:hira03:20200707114503p:plain
matplotlib01_05

figureとaxの生成を同時に行う

先ほどは、4つのグラフを配置する際に、Axesを4回インスタンス化して描画を行いましたが、以下のように描くことで、FigureとAxesを同時にインスタンス化することもできます。これは、subplotsを使ってFigureとAxesを同時にインスタンス化しています。この場合は、引数として何行何列、グラフサイズなどの引数を指定しすることで、サイズを指定したFigureと、何行何列のグラフなのかというAxesが生成されます。

fig, axes = plt.subplots(2,2, figsize = (12, 8))

f:id:hira03:20200707114537p:plain
matplotlib01_06

axesの中身を確認する

Axesがどのようなデータを持っているのかを確認してみると、以下のような多次元配列になっていることができます。また、配列の形状をshapeで確認してみると、2行2列の配列となっていることもわかります。

axes

array([[<matplotlib.axes.subplots.AxesSubplot object at 0x113c15e80>,
<matplotlib.axes.
subplots.AxesSubplot object at 0x113f67080>],
[<matplotlib.axes.subplots.AxesSubplot object at 0x113f93fd0>,
<matplotlib.axes.
subplots.AxesSubplot object at 0x113fcff98>]],
dtype=object)

axes.shape

(2, 2)

行と列を指定してグラフを描画する

先ほど生成したやり方で、複数のグラフを描画する場合は、以下のようになります。Axesは2行2列の配列データになっているので、例えば左上に配置したい場合は、[0][0]のインデックスを指定することで左上にグラフを配置することができます。

fig, axes = plt.subplots(2,2, figsize = (12, 8))

axes[0][0].plot(x_1,y_1)
axes[0][1].plot(x_2,y_2)
axes[1][0].plot(x_3,y_3)
axes[1][1].plot(x_4,y_4)
plt.show()

f:id:hira03:20200707114608p:plain
matplotlib01_07

axesを一次元配列に変換してグラフを描画

Axesは多次元配列になっているので、ravelを使って1次元配列に変換することによって、番号順で配置位置を指定することもできます。これは例えば、for文などでグラフ描画をまとめて行いたいときに必要な処理となります。

fig, axes = plt.subplots(2,2, figsize = (12, 8))

axes.ravel()[0].plot(x_1,y_1)
axes.ravel()[1].plot(x_2,y_2)
axes.ravel()[2].plot(x_3,y_3)
axes.ravel()[3].plot(x_4,y_4)

plt.show()

f:id:hira03:20200707114636p:plain
matplotlib01_08

pandasの基本的な使い方その8

pandasを使ったデータ分析の便利な機能として、データフレームのデータに関数を適用することができるということがあります。これはデータ追加の時にも少し紹介しましたが、pandasのデータフレームに関数を適用することによって、データごとの計算結果を新たなcolumnsとして追加することができます。この記事では、pandasの便利な機能の一つである関数の適用について紹介しています。

ランダムな整数の2次元配列を生成

関数の適用をテストするために、ここでは整数の乱数を生成しています。

import numpy as np
import pandas as pd

np.random.seed(10)
df = pd.DataFrame(data = np.random.randint(0,20,(5,5)), index = ['C1','C2','C3','C4','C5'],
        columns = ['A','B','C','D','E'])
df
A B C D E
C1 9 4 15 0 17
C2 16 17 8 9 0
C3 10 8 4 19 16
C4 4 15 11 11 1
C5 8 4 14 17 19

関数の適用

pandasを使って関数を適用するためには、以下のように、まず適用させたい関数を書きます。次にデータフレームに、新しいcolumnを作って関数を適用した結果をその新しいcolumnsに出力します。

def square(x):
    return x**2
df["A_square"] = df["A"].apply(square)
df
A B C D E A_square
C1 9 4 15 0 17 81
C2 16 17 8 9 0 256
C3 10 8 4 19 16 100
C4 4 15 11 11 1 16
C5 8 4 14 17 19 64

複数の引数をとる関数

関数は、複数の引数をとることもできます。以下の例では、x+yという関数となっているので、2つの引数を指定します。この場合は、columnsのAとBをそれぞれxとyの引数として指定しています。計算結果は、A_add1_Bとして出力しています。

def add1(x, y):
    return x + y
df["A_add1_B"] = add1(df["A"], df["B"])
df
A B C D E A_square A_add1_B
C1 9 4 15 0 17 81 13
C2 16 17 8 9 0 256 33
C3 10 8 4 19 16 100 18
C4 4 15 11 11 1 16 19
C5 8 4 14 17 19 64 12

データフレームを引数とする関数

関数は、データフレーム自体を引数にしてしまうこともできます。この場合は、戻り値であるreturnのところにdf["A"] + df["B"]という計算式を書いています。なので、このデータフレームにあったcolumnsがないとエラーとなります。

def add2(df):
    return df["A"] + df["B"]
df["A_add2_B"] = df.apply(add2, axis = 1)
df
A B C D E A_square A_add1_B A_add2_B
C1 9 4 15 0 17 81 13 13
C2 16 17 8 9 0 256 33 33
C3 10 8 4 19 16 100 18 18
C4 4 15 11 11 1 16 19 19
C5 8 4 14 17 19 64 12 12

複数の戻り値がある関数

関数は、計算結果の戻り値を複数にすることもできます。以下の例は、xという引数に対して、戻り値をxの2乗と3乗の二つの値を返す関数となっています。なので、追加するcolumnsも、df'A_square', 'A_cubed'というように2つのcolumnsにしています。

def square_and_cube(x):
    return pd.Series([x**2, x**3])
df[['squareA', 'cubedA']] = df["A"].apply(square_and_cube)
df
A B C D E A_square A_add1_B A_add2_B squareA cubedA
C1 9 4 15 0 17 81 13 13 81 729
C2 16 17 8 9 0 256 33 33 256 4096
C3 10 8 4 19 16 100 18 18 100 1000
C4 4 15 11 11 1 16 19 19 16 64
C5 8 4 14 17 19 64 12 12 64 512