Home

統計分析とPythonプログラミング

平均分散・標準偏差相関係数棒グラフ折れ線グラフヒストグラム散布図

Matplotlibのマーカーとカラー

 

本ウェブサイトは、このウェブサイトの説明を詳しくしたものである。サンプルスクリプトなどのファイルは、圧縮ファイルSimpleStatDetailed.zipにまとめた。ダウンロード展開すれば、自由に利用できる。

なお、統計学についての解説を<岡本安晴「データを使いこなすための統計入門」22世紀アート>で行っている。

また、Pythonデータ分析の解説を<岡本安晴「いまさら聞けないPythonでデータ分析」丸善出版>で行っている。

 

 

平均

 

M.110個のデータの和を求めてみる。

M.1 10個のデータ

66, 59, 62, 64, 63,68, 65, 59, 68, 64

 

まず、10個のデータの和は、10個のデータをリストdataで表して、リストの要素を1つずつ足して求めることができる。すなわち、次のスクリプト

 

data = [66, 59, 62, 64, 63,68, 65, 59, 68, 64]

s = 0

for v in data:

    s += v

print('s =', s)

 

を実行すると、次のように和が表示される。

 

s = 638

 

平均は、データの和をデータ全体に等しく分けたときの1個当たりの値であるので、和を個数で割った値、すなわち次のスクリプトで求めることができる。

 

m = s / len(data)

print('m =', m)

 

上のスクリプトを実行すると、次の出力を得る。

 

m = 63.8

 

和は、和を求める関数sumを用いると、次のスクリプトで求めることができる。

 

s1 = sum(data)

print('s1 =', s1)

 

上のスクリプトを実行すると、次の出力を得る。

 

s1 = 638

 

平均値は、ライブラリnumpyの関数meanで求めることができる。

ライブラリnumpyは次のコマンドでインストールできる。

 

PS C:\Users\Yasuharu> pip install numpy

 

次のスクリプトはnumpyの関数meanにより平均を求めるものである。

 

import numpy

m1 = numpy.mean(data)

print('m1 =', m1)

 

実行すると、次の出力を得る。

 

m1 = 63.8

 

以上のスクリプトをリストM.1のようにまとめた。

 

 

リストM.1 平均値の計算例(calc_mean_1.py

 

data = [66, 59, 62, 64, 63,68, 65, 59, 68, 64]

s = 0

for v in data:

    s += v

print('s =', s)

m = s / len(data)

print('m =', m)

 

s1 = sum(data)

print('s1 =', s1)

import numpy

m1 = numpy.mean(data)

print('m1 =', m1)

 

 

リストM.1を実行すると、以下の出力を得る。

 

s = 638

m = 63.8

s1 = 638

m1 = 63.8

 

 

データが、表計算ソフトで表の形で用意されている場合を考える。表計算ソフトは、Excelとか(無料)Open Office Calcがある。図M.1は、Open Office Calcで表を用意したものである。

M.1

 

ファイル拡張子を「.csv」に指定すると、CSV形式のファイルとして保存される。CSV形式は、岡本(2019pp. 33-35でも説明している。

CSV形式のファイルとして用意されたデータの読み込みは、モジュールpandasを用いると簡単にできる。

CSVファイルは、プログラムから読み込む前に保存しておく必要がある。既にあるファイルを修正した場合も、保存の操作を行わないと、修正したデータの読み込みはできない。また、データの保存は、スクリプトファイルと同じフォルダに保存しておくと、プログラムからファイル名を指定するときに簡単である。

M.1のファイルonecol.csvは、次のコードで読み込める。

 

csv_data = pandas.read_csv('onecol.csv')

 

上のコードにより、CSV形式のデータファイルonecol.csvが読み込まれて、pandasDataFrameという型のオブジェクトに変換される。DataFrameは辞書型のリストのようなもので、いろいろ便利な機能が用意されている。

DataFrame型のオブジェクトcsv_dataを、次のコードで書き出してみる。

 

print('csv_data =\n', csv_data)

 

以下の出力を得る。

 

csv_data =

    66

0  59

1  62

2  64

3  63

4  68

5  65

6  59

7  68

8  64

 

最初の「66」はキーとして扱われている。左1列目の数字は、データの通し番号である。読み込まれた値は、キーの下に書き出されている。

データの値だけを取り出すときは、アトリビュートvaluesで取り出せる。

 

csv_data.values

 

次のコードは、取り出した値を出力するものである。

 

print('\ncsv_data.values =\n', csv_data.values)

 

上のコードにより、以下の出力が得られる。

 

csv_data.values =

 [[59]

 [62]

 [64]

 [63]

 [68]

 [65]

 [59]

 [68]

 [64]]

 

9行×1行の配列の形になっている。これは、numpyの配列型ndarray型である。アトリビュートvaluesにより、値がndarray型として得ることができる。Numpyの配列ndarrayは、いろいろ便利な機能が用意されている配列である。

 

上の例では、図M.1の表において、1行目がDataFrameのキーとして扱われていて、データの値から抜けている。1行目からデータとして取り込むときは、パラメータheader=Noneを指定して読み込む。次のコードで読み込むと、1行目からデータの値として取り込める。

 

csv_data = pandas.read_csv('onecol.csv', header=None)

 

1行目がデータの値として取り込めていることは、上のコードに続けて以下のコードを実行すると確かめることができる。

 

print(csv_data)

print('\n', csv_data.values)

 

上のコードを実行すると、以下の出力を得る。

 

    0

0  66

1  59

2  62

3  64

4  63

5  68

6  65

7  59

8  68

9  64

 

 [[66]

 [59]

 [62]

 [64]

 [63]

 [68]

 [65]

 [59]

 [68]

 [64]]

 

DataFrameのキーとして、0が自動生成されていることが分かる。

 

平均値は、numpyの関数numpy.meanで計算できる。

 

m = numpy.mean(csv_data.values)

print('\nMean =', m)

 

上のスクリプトを実行すると、次の出力を得る。

 

Mean = 63.8

 

 

上の説明を、リストM.2にまとめた。

 

 

リストM.2 CSVファイルからの読み込み(calc_onecol.py

 

import numpy

import pandas

 

csv_data = pandas.read_csv('onecol.csv')

print('csv_data =\n', csv_data)

print('\ncsv_data.values =\n', csv_data.values)

 

print('\nheader=None')

csv_data = pandas.read_csv('onecol.csv', header=None)

print(csv_data)

print('\n', csv_data.values)

m = numpy.mean(csv_data.values)

print('\nMean =', m)

 

 

リストM.2を実行すると、以下の出力を得る。

 

csv_data =

    66

0  59

1  62

2  64

3  63

4  68

5  65

6  59

7  68

8  64

 

csv_data.values =

 [[59]

 [62]

 [64]

 [63]

 [68]

 [65]

 [59]

 [68]

 [64]]

 

header=None

    0

0  66

1  59

2  62

3  64

4  63

5  68

6  65

7  59

8  68

9  64

 

 [[66]

 [59]

 [62]

 [64]

 [63]

 [68]

 [65]

 [59]

 [68]

 [64]]

 

Mean = 63.8

 

 

変数が複数の場合は、以下のようになる。

 

M.2CSVファイルは、2変数XYの場合である。

M.2

 

M.2のファイルを、次のコードで読み込んでみる。

 

csv_data = pandas.read_csv('twocols.csv')

 

読み込まれたデータは、DataFrame型のオブジェクトとして作成されている。次のコードで書き出してみる。

 

print('csv_data =\n', csv_data)

 

以下の出力を得る。

 

csv_data =

    X  Y

0  1  4

1  2  5

2  3  6

 

DataFrameのキーとしてXYが設定されている。これは、CSVファイルから読み込むときに、1行目に設定されているものである。

1列目は、データの通し番号である。

データの値だけを取り出すときは、アトリビュートvaluesを用いる。

 

data = csv_data.values

 

取り出した値を、次のコードで出力してみる。

 

print('\ndata =\n', data)

 

実行すると、以下の出力を得る。

 

data =

 [[1 4]

 [2 5]

 [3 6]]

 

3行×2列のndarray型の配列として得られていることが分かる。

DataFrameのキーは、次のコードで得ることができる。

 

var_names = [v for v in csv_data.keys()]

 

次のコードで、出力してみる。

 

print('\nvar_names =', var_names)

 

実行すると、次の出力を得る。

 

var_names = ['X', 'Y']

 

データ全体の平均は、numpyの関数meanで求めることができる。

 

print('mean =', numpy.mean(data))

 

上のコードを実行すると、次の出力を得る。

 

mean = 3.5

 

列単位での平均を求めるときは、パラメータaxis=0、行単位で平均をとるときはパラメータaxis=1を付ける。

 

print('mean(axis=0) =', numpy.mean(data, axis=0))

print('mean(axis=1) =', numpy.mean(data, axis=1))

 

上のスクリプトを実行すると、次の出力を得る。

 

mean(axis=0) = [2. 5.]

mean(axis=1) = [2.5 3.5 4.5]

 

 

上の説明をリストM.3にまとめた。

 

 

リストM.3 複数の変数からなるCSVファイルの読み込み(calc_twocols.py

 

import numpy

import pandas

 

csv_data = pandas.read_csv('twocols.csv')

print('csv_data =\n', csv_data)

data = csv_data.values

print('\ndata =\n', data)

var_names = [v for v in csv_data.keys()]

print('\nvar_names =', var_names)

print('mean =', numpy.mean(data))

print('mean(axis=0) =', numpy.mean(data, axis=0))

print('mean(axis=1) =', numpy.mean(data, axis=1))

 

 

リストM.3を実行すると、以下の出力を得る。

 

csv_data =

    X  Y

0  1  4

1  2  5

2  3  6

 

data =

 [[1 4]

 [2 5]

 [3 6]]

 

var_names = ['X', 'Y']

mean = 3.5

mean(axis=0) = [2. 5.]

mean(axis=1) = [2.5 3.5 4.5]

 

 

 

分散・標準偏差

 

データの値、・・・、の散らばりの程度を表す指標として、分散あるいは標準偏差などがある。

いま、平均値を

と置いたとき、散らばり具合を、データの各値が平均値からどれくらい離れているかを表すと、次の値

は、データ値が平均値より大きいとき正の値、データ値が平均値より小さいとき負の値を取る。2乗して正の値にしてから平均を求める。

このは、分散(variance)と呼ばれている。

分散は、サンプルデータの散らばりを表すものである。データがある母集団からのサンプルであると考えた場合には、データから算出された分散は母集団の分散より小さくなる傾向(バイアス)があるので、母集団の分散の推定値としてのバイアスを補正した値

が使われる。は不偏分散と呼ばれている。分散の存在しない(無限大)分布もあるので、不偏分散が常に意味を持つとは限らない。

分散は、2乗和であるので、例えば、体重のデータの場合、単位がとなる。これをに戻すために平方根を取ると説明されることがある。

分散あるいは不偏分散の平方根は標準偏差(standard deviation)と呼ばれている。

 

具体的に、表V.1のデータについて考える。

 

V.1 

3,  6,  4,  5

 

V.1のデータの平均は

である。したがって、分散は

となる。不偏分散は

である。

分散から導かれる標準偏差は

不偏分散から導かれる標準偏差は

である。

 

上の計算をPythonスクリプトで行ってみる。

V.1のデータをリストで表してみる。

 

data = [3,6,4,5]

print('data =', data)

 

上のスクリプトを実行すると、次の出力を得る。

 

data = [3, 6, 4, 5]

 

配列の計算は、numpyndarray型を用いると便利であるので、次のようにリストdatanumpyndarray型に変換する。

 

import numpy as np

a = np.array(data)

print('a =', a)

 

上のスクリプトを実行すると、次の出力を得る。

 

a = [3 6 4 5]

 

平均は、numpyの関数meanにより求めることができる。

 

m = np.mean(a)

print('mean =', m)

 

上のスクリプトを実行すると、次の出力を得る。

 

mean = 4.5

 

データと平均との差は、次のスクリプトで求まる。

 

a_m = a - m

print('a - m =', a_m)

 

実行すると、次の出力を得る。

 

a - m = [-1.5  1.5 -0.5  0.5]

 

データと平均との差の2乗は、次のスクリプトで得ることができる。

 

ss = a_m ** 2

print('ss =', ss)

 

実行すると、次の出力を得る。

 

ss = [2.25 2.25 0.25 0.25]

 

従って、分散は差の2乗の平均として、次のスクリプトで求めることができる。

 

var = np.mean(ss)

print('var =', var)

 

実行すると、次の出力を得る。

 

var = 1.25

 

不偏分散(unbiased variance)は、次のスクリプトで得ることができる。

 

var_u = np.sum(ss) / (len(a) - 1)

print('var_u =', var_u)

 

実行すると、次の出力を得る。

 

var_u = 1.6666666666666667

 

標準偏差(standard deviation)は、分散の平方根として次のスクリプトで得ることができる。

 

sd_var = var ** 0.5

print('sd(var) =', sd_var)

sd_var_u = var_u ** 0.5

print('sd(var_u) =', sd_var_u)

 

実行すると、以下の出力を得る。

 

sd(var) = 1.118033988749895

sd(var_u) = 1.2909944487358056

 

 

分散と標準偏差は、numpyの関数によって求めることもできる。パラメータddof=1を設定すると不偏分散が算出される。

 

var_1 = np.var(a)

print('var_1 =', var_1)

var_u_1 = np.var(a, ddof=1)

print('var_u_1 =', var_u_1)

sd_var_1 = np.std(a)

print('sd_var_1 =', sd_var_1)

sd_var_u_1 = np.std(a, ddof=1)

print('sd_var_u_1 =', sd_var_u_1)

 

 

上のスクリプトを実行すると、以下の出力が得られる。

 

var_1 = 1.25

var_u_1 = 1.6666666666666667

sd_var_1 = 1.118033988749895

sd_var_u_1 = 1.2909944487358056

 

 

上の説明をまとめると、リストV.1のようになる。

 

 

リストV.1 分散・標準偏差の計算(calc_var_sd.py

 

data = [3,6,4,5]

print('data =', data)

import numpy as np

a = np.array(data)

print('a =', a)

m = np.mean(a)

print('mean =', m)

a_m = a - m

print('a - m =', a_m)

ss = a_m ** 2

print('ss =', ss)

var = np.mean(ss)

print('var =', var)

var_u = np.sum(ss) / (len(a) - 1)

print('var_u =', var_u)

sd_var = var ** 0.5

print('sd(var) =', sd_var)

sd_var_u = var_u ** 0.5

print('sd(var_u) =', sd_var_u)

print()

var_1 = np.var(a)

print('var_1 =', var_1)

var_u_1 = np.var(a, ddof=1)

print('var_u_1 =', var_u_1)

sd_var_1 = np.std(a)

print('sd_var_1 =', sd_var_1)

sd_var_u_1 = np.std(a, ddof=1)

print('sd_var_u_1 =', sd_var_u_1)

 

 

リストV.1を実行すると、以下の出力を得る。

 

data = [3, 6, 4, 5]

a = [3 6 4 5]

mean = 4.5

a - m = [-1.5  1.5 -0.5  0.5]

ss = [2.25 2.25 0.25 0.25]

var = 1.25

var_u = 1.6666666666666667

sd(var) = 1.118033988749895

sd(var_u) = 1.2909944487358056

 

var_1 = 1.25

var_u_1 = 1.6666666666666667

sd_var_1 = 1.118033988749895

sd_var_u_1 = 1.2909944487358056

 

 

標準得点(standardized score):z得点(z score

CSVファイルへの保存

 

例えば、身長のデータは、mを単位とする場合とpを単位とする場合とで数値が100倍異なる。データの単位の影響を除いて、データの統計学的分析を行うときには、データを平均が0,分散が1であるように変換した値が用いられる。この値はz得点と呼ばれているが、一般に、データを何らかの基準で標準化した値は、標準得点(standardized score)と呼ばれている(岡本、2022pp. 18-19)。

z得点は、次式で求められる。

V.1のデータについて考える。

V.1

 

次のスクリプトで、図V.1CSV形式のファイルdata.csvpandasDataFrame型のオブジェクトとして読み込み、csv_dataで指し示す。

 

csv_data = pd.read_csv('data.csv')

 

読み込まれたDataFrame型のオブジェクトのキーとデータ値は、次のスクリプトで表示できる。

 

print('csv_data =\n', csv_data)

names = [v for v in csv_data.keys()]

print('names =\n', names)

data = csv_data.values

print('data =\n', data)

 

上のスクリプトを実行すると、以下の出力を得る。

 

csv_data =

    X   Y

0  3  30

1  6  60

2  4  40

3  5  50

names =

 ['X', 'Y']

data =

 [[ 3 30]

 [ 6 60]

 [ 4 40]

 [ 5 50]]

 

次のコードで、csv_dataのキー「'X'」のデータを取りだし、Xで指し示す。

 

X = np.array(csv_data['X'])

print('X =\n', X)

 

上のコードを実行すると、次の出力を得る。

 

X =

 [3 6 4 5]

 

平均と標準偏差は次のスクリプトで求められる。

 

meanX = np.mean(X)

sdX = np.std(X)

print('meanX =', meanX, '   sdX =', sdX)

 

上のスクリプトを実行すると、次の出力を得る。

 

meanX = 4.5    sdX = 1.118033988749895

 

これらより、のz得点、は次のスクリプトで求められ、配列z_Xで表される。

 

z_X = (X - meanX) / sdX

print('z_X =\n', z_X)

 

上のスクリプトを実行すると、次の出力を得る。

 

z_X =

 [-1.34164079  1.34164079 -0.4472136   0.4472136 ]

 

 

DataFrame csv_dataのキー「'Y'」のデータも、Yで表して、上の処理と同様に以下のスクリプトによる処理を行う。

 

Y = np.array(csv_data['Y'])

print('Y =\n', Y)

meanY = np.mean(Y)

sdY = np.std(Y)

print('meanY =', meanY, '   sdY =', sdY)

z_Y = (Y - meanY) / sdY

print('z_Y =\n', z_Y)

 

実行すると、以下の出力を得る。

 

Y =

 [30 60 40 50]

meanY = 45.0    sdY = 11.180339887498949

z_Y =

 [-1.34164079  1.34164079 -0.4472136   0.4472136 ]

 

Yは、X10倍したものなので、2つのz得点z_Xz_Yは同じ値である。

 

上で得られたz得点を、DataFrame csv_dataにキー「'z_X'」および「'z_Y'」のもとに追加する。

 

csv_data['z_X'] = z_X

csv_data['z_Y'] = z_Y

print(csv_data)

 

上のスクリプトを実行すると、以下の出力を得る。

 

   X   Y       z_X       z_Y

0  3  30 -1.341641 -1.341641

1  6  60  1.341641  1.341641

2  4  40 -0.447214 -0.447214

3  5  50  0.447214  0.447214

 

キー「'z_X'」および「'z_Y'」のデータの追加されたDataFrame csv_dataを、DataFramecsv_data.to_csv関数によりCSV形式のファイルcheck_1.csvに格納する。ファイル名は、拡張子「.csv」を付けて任意である。

 

with open('check_1.csv', 'w') as f_csv:

    csv_data.to_csv(f_csv, index=False, lineterminator='\n')

 

上のスクリプトの実行後、CSVファイルcheck_1.csvを開くと、図V.2のようである。

V.2

 

z得点は、ライブライscipyの関数scipy.stats.zscore求めることもできる。

 

import scipy

z = scipy.stats.zscore(X)

print('z =\n', z)

 

上のスクリプトを実行すると、以下の出力を得る。

 

z =

 [-1.34164079  1.34164079 -0.4472136   0.4472136 ]

 

 

上の説明を、リストV.2にまとめた。

 

 

リストV.2 z得点(calc_z_score.py

 

import numpy as np

import pandas as pd

 

csv_data = pd.read_csv('data.csv')

print('csv_data =\n', csv_data)

names = [v for v in csv_data.keys()]

print('names =\n', names)

data = csv_data.values

print('data =\n', data)

X = np.array(csv_data['X'])

print('X =\n', X)

meanX = np.mean(X)

sdX = np.std(X)

print('meanX =', meanX, '   sdX =', sdX)

z_X = (X - meanX) / sdX

print('z_X =\n', z_X)

Y = np.array(csv_data['Y'])

print('Y =\n', Y)

meanY = np.mean(Y)

sdY = np.std(Y)

print('meanY =', meanY, '   sdY =', sdY)

z_Y = (Y - meanY) / sdY

print('z_Y =\n', z_Y)

csv_data['z_X'] = z_X

csv_data['z_Y'] = z_Y

print(csv_data)

 

with open('check_1.csv', 'w') as f_csv:

    csv_data.to_csv(f_csv, index=False, lineterminator='\n')

 

import scipy

z = scipy.stats.zscore(X)

print('z =\n', z)

 

 

リストV.2を実行すると、以下の出力を得る。

 

 

csv_data =

    X   Y

0  3  30

1  6  60

2  4  40

3  5  50

names =

 ['X', 'Y']

data =

 [[ 3 30]

 [ 6 60]

 [ 4 40]

 [ 5 50]]

X =

 [3 6 4 5]

meanX = 4.5    sdX = 1.118033988749895

z_X =

 [-1.34164079  1.34164079 -0.4472136   0.4472136 ]

Y =

 [30 60 40 50]

meanY = 45.0    sdY = 11.180339887498949

z_Y =

 [-1.34164079  1.34164079 -0.4472136   0.4472136 ]

   X   Y       z_X       z_Y

0  3  30 -1.341641 -1.341641

1  6  60  1.341641  1.341641

2  4  40 -0.447214 -0.447214

3  5  50  0.447214  0.447214

z =

 [-1.34164079  1.34164079 -0.4472136   0.4472136 ]

 

 

 

相関係数

 

2つの変量の増減の関係を考える。

C.1のデータの場合、Xの値が増加するとYの値も増加している。

C.1 SamplePのデータ

 

C.2のデータの場合、Xの値が増加すると、Yの値は減少している。

C.2 SampleNのデータ

 

2つのデータをまとめて散布図で表すと、図C.3のようになる。

C.

 

平均値(赤の星印の位置)からXの値が増加するとYの値はSamplePでは平均値から増加しており、SampleNでは減少している。平均値からXの値が減少すると、Yの値はSamplePでは減少しており、SampleNでは増加している。この関係は次の式(C.1)の値に反映される。

すなわち、SamplePでは式(C.1)の値は常に正であり、SampleNでは負である。

実際のデータでは、式(C.1)の値がすべてのデータの対に対して正、あるいは負であるとは限らないので、平均値をとってデータ全体の傾向を見る。このデータ全体にわたる式(C.1)の平均値は、共分散(covariance)と呼ばれている。

いま、データSampleP(図C.1)を次のスクリプトで読み込む。

 

import pandas as pd

import numpy as np

 

with open('SampleP.csv', 'r') as f:

    csv_data = pd.read_csv(f)

print('csv_data =\n', csv_data)

X = np.array(csv_data['X'])

print('X =\n', X)

Y = np.array(csv_data['Y'])

print('Y =\n', Y)

 

上のスクリプトを実行すると、以下の出力を得る。

 

csv_data =

    X  Y

0  1  1

1  2  2

2  3  4

3  4  5

X =

 [1 2 3 4]

Y =

 [1 2 4 5]

 

1列目のデータがXに、2列目のデータがYに設定されたことが分かる。

XY、それぞれの平均値を求め、式(C.2)により共分散を求めるスクリプトを以下のように用意した。

 

mean_X = np.mean(X)

mean_Y = np.mean(Y)

cov = np.mean((X - mean_X) * (Y - mean_Y))

print('cov =', cov)

 

実行すると、次の結果を得る。

 

cov = 1.75

 

Pythonには、共分散を求める関数が用意されている。次のスクリプトは、Numpyの関数covを用いた例である。

 

ck_cov = np.cov(X, Y, ddof=0)

print('ck_cov =', ck_cov)

 

引数ddof=0は、平均を求めるときにデータ数で割ることを指定するものである。

実行すると、次の出力を得る。

 

ck_cov = [[1.25 1.75]

 [1.75 2.5 ]]

 

関数covは、共分散行列を返すので、対角線上に分散、非対角要素に共分散が格納されている。

対角線上に分散が格納されていることを確認するために、次のスクリプトを用意した。

 

print('V(X) =', np.var(X), '   V(Y) =', np.var(Y))

 

実行すると、次の結果を得る。

 

V(X) = 1.25    V(Y) = 2.5

 

共分散は、2変数の間の関係を表すが、その大きさは変量の単位にも依存している。身長と体重の関係を共分散で表すとき、pとgの場合の値は、mとsの場合の100,000倍になる。単位の影響を避けるため、単位を統計学的な単位とした標準得点の共分散が用いられ、この場合の共分散は相関係数と呼ばれている。すなわち、

である。

コーシー・シュワルツの不等式(岡本、2009p.54)から

が直ちに導かれるので、

の成り立つことが分かる。

XYの標準得点を求め、その共分散として相関係数を求めるスクリプトを以下のように用意した。標準得点の平均は0であることに注意。

 

z_X = (X - mean_X) / np.std(X)

z_Y = (Y - mean_Y) / np.std(Y)

print('z_X =\n', z_X)

print('z_Y =\n', z_Y)

 

corr = np.mean(z_X * z_Y)

print('corr =', corr)

 

上のスクリプトを実行すると、以下の出力を得る。

 

z_X =

 [-1.34164079 -0.4472136   0.4472136   1.34164079]

z_Y =

 [-1.26491106 -0.63245553  0.63245553  1.26491106]

corr = 0.9899494936611666

 

numpyの相関係数を求める関数corrcoefを用いるスクリプトは、次のようになる。

 

corr_ck = np.corrcoef(X, Y)

print('corr_ck =', corr_ck)

 

関数corrcoefの返り値は相関行列であるので、上のスクリプトの実行結果は次のようになる。

 

corr_ck = [[1.         0.98994949]

 [0.98994949 1.        ]]

 

Scipyの関数pearsonrを用いる場合のスクリプトは以下のようである。式(C.3)で与えられる相関係数は、ピアソンの積率相関係数と呼ばれている。

 

import scipy

corr_ck1 = scipy.stats.pearsonr(X, Y).statistic

print('corr_ck1 =\n', corr_ck1)

 

相関係数は、関数pearsonrの戻り値のstatisticの値として与えられる。

上のスクリプトを実行すると、次の出力を得る。

 

corr_ck1 =

 0.9899494936611666

 

 

上の説明を、リストC.1としてまとめた。

 

リストC.1 相関係数の計算(calc_corr.py

 

import pandas as pd

import numpy as np

 

with open('SampleP.csv', 'r') as f:

    csv_data = pd.read_csv(f)

print('csv_data =\n', csv_data)

X = np.array(csv_data['X'])

print('X =\n', X)

Y = np.array(csv_data['Y'])

print('Y =\n', Y)

 

mean_X = np.mean(X)

mean_Y = np.mean(Y)

cov = np.mean((X - mean_X) * (Y - mean_Y))

print('cov =', cov)

 

ck_cov = np.cov(X, Y, ddof=0)

print('ck_cov =', ck_cov)

 

print('V(X) =', np.var(X), '   V(Y) =', np.var(Y))

 

z_X = (X - mean_X) / np.std(X)

z_Y = (Y - mean_Y) / np.std(Y)

print('z_X =\n', z_X)

print('z_Y =\n', z_Y)

corr = np.mean(z_X * z_Y)

print('corr =', corr)

 

corr_ck = np.corrcoef(X, Y)

print('corr_ck =', corr_ck)

 

import scipy

corr_ck1 = scipy.stats.pearsonr(X, Y).statistic

print('corr_ck1 =\n', corr_ck1)

 

 

 

リストC.1を実行すると、以下の出力を得る。

 

csv_data =

    X  Y

0  1  1

1  2  2

2  3  4

3  4  5

X =

 [1 2 3 4]

Y =

 [1 2 4 5]

cov = 1.75

ck_cov = [[1.25 1.75]

 [1.75 2.5 ]]

V(X) = 1.25    V(Y) = 2.5

z_X =

 [-1.34164079 -0.4472136   0.4472136   1.34164079]

z_Y =

 [-1.26491106 -0.63245553  0.63245553  1.26491106]

corr = 0.9899494936611666

corr_ck = [[1.         0.98994949]

 [0.98994949 1.        ]]

corr_ck1 =

 0.9899494936611666

 

 

リストC.1のスクリプトにおいて、入力ファイルを図C.2SampleN.csvとするために、

 

with open('SampleN.csv', 'r') as f:

    csv_data = pd.read_csv(f)

 

と変えて実行すると、以下のように負の相関係数が得られる。

 

 

csv_data =

    X  Y

0  1  5

1  2  4

2  3  2

3  4  1

X =

 [1 2 3 4]

Y =

 [5 4 2 1]

cov = -1.75

ck_cov = [[ 1.25 -1.75]

 [-1.75  2.5 ]]

V(X) = 1.25    V(Y) = 2.5

z_X =

 [-1.34164079 -0.4472136   0.4472136   1.34164079]

z_Y =

 [ 1.26491106  0.63245553 -0.63245553 -1.26491106]

corr = -0.9899494936611666

corr_ck = [[ 1.         -0.98994949]

 [-0.98994949  1.        ]]

corr_ck1 =

 -0.9899494936611666

 

 

 

Pythonにおける統計関係の関数について

 

Pythonにも統計関係の関数が多数用意されている。以下のウェブサイト

 

https://numpy.org/doc/stable/reference/routines.statistics.html

 

https://docs.scipy.org/doc/scipy/reference/stats.html

 

などを参照されたい。

 

 

 

棒グラフ

 

B.1のデータは、e-Statからダウンロードした(2023.11.22)統計名「国民栄養・健康調査」、表番号14のデータから2019年の20歳〜29歳の身長データを抜き出したものである。

B.1

 

身長の棒グラフを描くために、リストB.1のスクリプトを作成した。

 

 

リストB.1 簡単な棒グラフ作成スクリプト(simple.py

 

import matplotlib.pyplot as plt

import japanize_matplotlib        #   日本語表示用モジュール

 

plt.bar(['男性', '女性'], [171.5, 157.5])

plt.show()

 

 

棒グラフ描画コードは次の1行である。

 

plt.bar(['男性', '女性'], [171.5, 157.5])

 

関数plt.barの第1パラメータに、棒グラフのバーに対するラベル['男性', '女性']を指定し、第2パラメータに各バーの値[171.5, 157.5]を指定している。

描かれたグラフは、スクリプト

 

plt.show()

 

の実行で表示される。

グラフでは、日本語による表記が行われるので、そのためのモジュールを次のコードでimportしている。

 

import japanize_matplotlib

 

このモジュールは、次のコマンドでインストールできる。

 

pip install japanize_matplotlib

 

リストB.1を実行すると、図B.2のグラフが表示される。

B.2

 

表示されたグラフは、保存ボタンをクリックしてファイルに保存することができる。

B.2のグラフに説明を加えたり、デフォルトの設定値を変更したりするために、リストB.2のスクリプトを作成した。

 

 

リストB.2 棒グラフの描画:詳細設定版(described_bar.py

 

import pandas as pd

import matplotlib.pyplot as plt

import japanize_matplotlib              #   日本語表示用モジュール

 

with open('身長.csv', 'r') as f:

    csv_data = pd.read_csv(f)           #   CSVファイルの読み込み

print('csv_data =\n', csv_data)

names = [v for v in csv_data.keys()]    #   キーのリスト

print('names =\n', names)

data = csv_data.values                  #    データのndarray

print('data =\n', data)

 

plt.title('身長:20歳〜29', fontsize = 20)

cntnr = plt.bar(names[1:], data[0][1:],        #   バーの名前と値

        color = ['lime', 'aqua'],              #   バーの色

        edgecolor = 'k',                       #   バーの枠の色

        width = 0.5,                           #   バーの幅

        linewidth = 3,                         #   バーの枠の線幅

        yerr = data[1][1:], capsize = 20,      #   エラーバーの長さ(標準偏差)とキャップの長さ

        error_kw ={'linewidth':10},            #   エラーバーの線幅

        ecolor='r')                            #   エラーバーの色

#   上で作成した棒グラフの情報cntnrのバーにラベルを付ける

plt.bar_label(cntnr, [f'{v}' for v in data[0][1:]],

              label_type = 'center', fontsize = 20)

plt.xticks(fontsize = 20)

plt.yticks(fontsize = 14)

plt.show()

 

 

リストB.2を実行すると、図B.3のグラフが表示される。

 

B.3

 

リストB.2では、次のスクリプトで図B.1CSVファイル身長.csvを読み込んでいる。

 

with open('身長.csv', 'r') as f:

    csv_data = pd.read_csv(f)           #   CSVファイルの読み込み

 

読み込まれたファイルの内容を、次のスクリプトで書き出している。

 

print('csv_data =\n', csv_data)

names = [v for v in csv_data.keys()]    #   キーのリスト

print('names =\n', names)

data = csv_data.values                  #    データのndarray

print('data =\n', data)

 

出力は、以下のようである。

 

csv_data =

      項目     男性     女性

0    身長  171.5  157.5

1  標準偏差    6.6    5.5

names =

 ['項目', '男性', '女性']

data =

 [['身長' 171.5 157.5]

 ['標準偏差' 6.6 5.5]]

 

リストB.2では、グラフの上部に表示する文字列をplt.titleで設定している。

 

plt.title('身長:20歳〜29', fontsize = 20)

cntnr = plt.bar(names[1:], data[0][1:],        #   バーの名前と値

        color = ['lime', 'aqua'],              #   バーの色

        edgecolor = 'k',                       #   バーの枠の色

        width = 0.5,                           #   バーの幅

        linewidth = 3,                         #   バーの枠の線幅

        yerr = data[1][1:], capsize = 20,      #   エラーバーの長さ(標準偏差)とキャップの長さ

        error_kw ={'linewidth':10},            #   エラーバーの線幅

        ecolor='r')                            #   エラーバーの色

 

関数plt.barのパラメータで、グラフの設定をいろいろ行っている。

関数の戻り値を

 

cntnr = plt.bar()

 

と識別子cntnrで保存しているのは、次のコードで使うためである。

Pythonでは、

 

識別子 = オブジェクト

 

の文は、左辺への代入ではなく、左辺の識別子を右辺のオブジェクトを指し示すものにするということであるが、簡単に「代入」というような言い方をすることが多い。

色の指定はいろいろなものが用意されているが、次のウェブサイトを参照されたい。

 

https://matplotlib.org/stable/gallery/color/named_colors.html

 

RGBで直接指定する例は、岡本(2019p.17にある

次のスクリプトは、バー内に文字列を表示するものである。

 

plt.bar_label(cntnr, [f'{v}' for v in data[0][1:]],

              label_type = 'center', fontsize = 20)

 

 

 

折れ線グラフ

 

東京都の2022年各月のデータを気象庁のホームページよりダウンロード(2023.11.25)したものから、平均気温、最高気温、最低気温を抜粋して図L.1CSVファイルのようにまとめた。

L.1 東京2022年(気象庁サイトよりダウンロード抜粋)

 

平均気温の折れ線を描くために、リストL.1のスクリプトを作成した。

 

 

リストL.1 簡単な折れ線グラフ描画スクリプト(simple.py

 

import pandas as pd

import matplotlib.pyplot as plt

import japanize_matplotlib              #   日本語表示用モジュール

 

with open('Tokyo2022.csv', 'r') as f:

    csv_data = pd.read_csv(f)           #   CSVファイルの読み込み

print('csv_data =\n', csv_data)

 

means = csv_data['平均気温'].values     #    平均気温データの取り出し

print('means =\n', means)

months = ['1月','2月','3月','4月','5月','6月',

          '7月','8月','9月','10月','11月','12月']

plt.plot(months, means)            #    折れ線のプロット

plt.show()

 

 

L.1のデータファイルTokyo2022.csvを次のスクリプトでcsv_dataに読み込んでいる。

 

with open('Tokyo2022.csv', 'r') as f:

    csv_data = pd.read_csv(f)         

 

読み込んだファイルから、次のスクリプトで平均気温を取り出している。

 

means = csv_data['平均気温'].values     #    平均気温データの取り出し

print('means =\n', means)

 

上のスクリプトを実行すると、次の出力が表示される。

 

means =

 [ 4.9  5.2 10.9 15.3 18.8 23.  27.4 27.5 24.4 17.2 14.5  7.5]

 

横軸(X軸)のデータのラベルをmonthsに設定して、次のスクリプトで折れ線を描いている。

 

months = ['1月','2月','3月','4月','5月','6月',

          '7月','8月','9月','10月','11月','12月']

plt.plot(months, means)            #    折れ線のプロット

 

リストL.1のスクリプトを実行すると、図L.2の折れ線グラフが表示される。

L.2

 

L.2は平均気温のみの折れ線であるが、これに最低気温と最高気温の折れ線も加えてみる。

L.3

 

L.3のグラフは、次のリストL.2のスクリプトで描いている。

 

リスト」L.2 平均気温、最高気温、最低気温の折れ線グラフ描画スクリプト(described.py

 

import pandas as pd

import matplotlib.pyplot as plt

import japanize_matplotlib              #   日本語表示用モジュール

 

with open('Tokyo2022.csv', 'r') as f:

    csv_data = pd.read_csv(f)           #   CSVファイルの読み込み

 

means = csv_data['平均気温'].values

print('means =\n', means)

maxs = csv_data['最高気温'].values

print('maximums =\n', maxs)

mins = csv_data['最低気温'].values

print('minimums =\n', mins)

 

plt.title('東京の気温(2022年)', fontsize = 24)

months = [f'{v}' for v in range(1,13)]

plt.plot(months, maxs, 'r', linewidth = 2, label = '最高気温')

plt.plot(months, means, 'k', linewidth = 3, label = '平均気温')

plt.plot(months, mins, 'cyan', linewidth = 2, label = '最低気温')

plt.hlines(0, '1', '12', linestyle = '--', color = 'cyan')

plt.hlines(35, '1', '12', linestyle = '--', color = 'r')

plt.ylabel('', fontsize = 16)

plt.legend()

plt.show()

 

 

 

まず、図L.1CSVファイルを読み込んでいる。

 

with open('Tokyo2022.csv', 'r') as f:

    csv_data = pd.read_csv(f)        

 

DataFrame csv_data から、平均値、最高気温、最低気温を取り出してmeansmaxsminsに設定している。

maxs

means = csv_data['平均気温'].values

print('means =\n', means)

maxs = csv_data['最高気温'].values

print('maximums =\n', maxs)

mins = csv_data['最低気温'].values

print('minimums =\n', mins)

 

上のスクリプトを実行すると、端末には以下の出力が表示される。

 

means =

 [ 4.9  5.2 10.9 15.3 18.8 23.  27.4 27.5 24.4 17.2 14.5  7.5]

maximums =

 [13.4 18.5 24.1 27.7 31.2 36.4 37.  36.4 32.7 29.6 24.3 15.9]

minimums =

 [-3.5 -1.9  0.5  3.6  9.3 14.7 21.8 18.6 16.5  8.5  7.7 -0.1]

 

グラフのタイトルと横軸に表示する文字列を、次のスクリプトで設定している。

 

plt.title('東京の気温(2022年)', fontsize = 24)

months = [f'{v}' for v in range(1,13)]

 

3本の折れ線は、次のスクリプトで描いている。

 

plt.plot(months, maxs, 'r', linewidth = 2, label = '最高気温')

plt.plot(months, means, 'k', linewidth = 3, label = '平均気温')

plt.plot(months, mins, 'cyan', linewidth = 2, label = '最低気温')

 

折れ線の色は、「'r'」などの名前で指定している。色の名前については、次のウェブサイトに説明がある。

 

https://matplotlib.org/stable/gallery/color/named_colors.html

 

色は、RGBでも指定できるが、岡本(2019p.17を参照されたい。

L.3では、0℃と35℃の位置に関数plt.hlinesによって破線が水平に引かれている。

 

plt.hlines(0, '1', '12', linestyle = '--', color = 'cyan')

plt.hlines(35, '1', '12', linestyle = '--', color = 'r')

 

線のスタイルlinestyleについては、次のウェブサイトに説明がある。

 

https://matplotlib.org/stable/gallery/lines_bars_and_markers/linestyles.html

 

岡本(2019pp.22-26でも説明している。

関数plt.plot()などでパラメータlabelが指定されている場合は、関数

 

plt.legend()

 

の実行で表示される。表示される場所は、自動で決まるが、パラメータlocで指定することもできる。パラメータlocの値と表示位置の関係は、ウェブサイト

 

https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.legend.html

 

を参照されたい。岡本(2019pp.17-18でも説明している。

 

 

 

ヒストグラム

 

気象庁のホームページから気象データをダウンロードして(2023.11.2720時ごろ)、全国の観測地点における最高気温と最低気温を取り出してH.1のようにまとめた。

H.1a

H.1b

 

H.1のファイル最高最低気温20231127.csvを読み込み、最高気温のヒストグラムを描くスクリプトを、リストH.1のように作成した。

 

 

リストH.1 最高気温のヒストグラム描画スクリプト(simple.py

 

import pandas as pd

import matplotlib.pyplot as plt

import japanize_matplotlib              #   日本語表示用モジュール

 

with open('最高最低気温20231127.csv', 'r') as f:

    csv_data = pd.read_csv(f)           #   CSVファイルの読み込み

 

maxs = csv_data['最高気温'].values      #   キー「最高気温」のデータ

plt.hist(maxs)                          #   バーグラフの描画

plt.show()

 

 

リストH.1のスクリプトを実行すると、図H.2のヒストグラムが描画される。

H.2

 

H.2のヒストグラムでは、bin(階級、級)が自動的に決められるので、階級の設定が必ずしも適切であるとは限らない。

これに対して、次のリストH.2のスクリプトでは、binの境界値が指定されており、軸のラベルなども設定されていて、グラフから情報を読み取り易い。

 

 

リストH.2 階級の境界値が指定されたヒストグラム(bins_given.py

 

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import japanize_matplotlib                      #   日本語表示用モジュール

 

with open('最高最低気温20231127.csv', 'r') as f:

    csv_data = pd.read_csv(f)                   #   CSVファイルの読み込み

 

maxs = csv_data['最高気温'].values              #   キー「最高気温」のデータの取り出し

print('min_v =', np.min(maxs), '   max_v =', np.max(maxs))

 

v_bins = np.arange(-5, 31, 5)                   #   bin境界値の設定

print('v_bins =\n', v_bins)

results = plt.hist(maxs, bins = v_bins)         #   ヒストグラムの描画

plt.title('最高気温', fontsize=20)

plt.xlabel('', fontsize=14)

plt.ylabel('度数', fontsize=14)

plt.show()

print('results =\n', results)                   #   bin情報の出力

 

 

リストH.2のスクリプトを実行すると、図H.3のヒストグラムが描かれる。

H.3

 

最高気温の最低値は−0.6、最高値は27.2であるので、階級の境界値を−5から始めて、5間隔で30までとしている。すなわち、

 

v_bins = np.arange(-5, 31, 5)                   #   bin境界値の設定

print('v_bins =\n', v_bins)

 

である。上のスクリプトを実行すると、次の出力を得る。

 

v_bins =

 [-5  0  5 10 15 20 25 30]

 

上の階級の境界値を用いて、次のスクリプトでヒストグラムを描いている。

 

results = plt.hist(maxs, bins = v_bins)

 

関数の戻り値resultsには、階級の情報が格納されている。

 

次のスクリプト

 

print('results =\n', results) 

 

を実行すると、以下の出力を得る。

 

results =

 (array([  1., 118., 151., 232., 340.,  47.,  26.]), array([-5.,  0.,  5., 10., 15., 20., 25., 30.]), <BarContainer object of 7 artists>)

 

最初のリストに各階級の度数が、2番目のリストに階級の境界値が示されている。

グラフのタイトルと軸のラベルが次のスクリプトで設定されている。

 

plt.title('最高気温', fontsize=20)

plt.xlabel('', fontsize=14)

plt.ylabel('度数', fontsize=14)

 

 

最高気温と最低気温のグラフを同時に表示することを考える(図H.4)。

H.4

 

H.4のグラフは、リストH.3のスクリプトで描いたものである。

 

 

リストH.3 最高気温と最低気温のヒストグラムの同時表示(mixed.py)。

 

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import japanize_matplotlib              #   日本語表示用モジュール

 

with open('最高最低気温20231127.csv', 'r') as f:

    csv_data = pd.read_csv(f)           #   CSVファイルの読み込み

 

maxs = csv_data['最高気温'].values      #   キー「最高気温」データの取り出し

mins = csv_data['最低気温'].values      #   キー「最低気温」データの取り出し

print('min(maxs) =', np.min(maxs), '   max(maxs) =', np.max(maxs))

print('min(mins) =', np.min(mins), '   max(mins) =', np.min(mins))

v_bins = np.arange(-15, 31, 5)

print('v_bins =\n', v_bins)

plt.title('最高気温と最低気温', fontsize=16)

results = plt.hist(                                   #   bin情報をresultsに返す

                   [maxs, mins],                      #   表示データのリスト

                   label = ['最高気温', '最低気温'],  #   表示データラベルのリスト

                   color = ['orange', 'b'],           #   表示データの色

                   bins = v_bins)                     #   binの境界値のリスト

plt.xlabel('', fontsize=16)

plt.ylabel('度数', fontsize=16)

plt.legend(fontsize=14)                 #   ラベルの表示

plt.show()

print('results =\n', results)           #   resultsの出力

 

 

複数のヒストグラムの同時提示は、それぞれのデータなどをリストとして設定することにより描くことができる。

 

results = plt.hist(                                   #   bin情報をresultsに返す

                   [maxs, mins],                      #   表示データのリスト

                   label = ['最高気温', '最低気温'],  #   表示データラベルのリスト

                   color = ['orange', 'b'],           #   表示データの色

                   bins = v_bins)                     #   binの境界値のリスト

 

 

2つのヒストグラムを別のグラフとして描くこともできる(図H.5)。

H.5

 

H.5のグラフは、リストH.4のスクリプトで描かれている。

 

 

リストH.4 2つのグラフを縦に並べて表示(two_hist.py

 

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import japanize_matplotlib              #   日本語表示用モジュール

 

with open('最高最低気温20231127.csv', 'r') as f:

    csv_data = pd.read_csv(f)           #   CSVファイルの読み込み

 

maxs = csv_data['最高気温'].values

print('maxs =\n', maxs[:5], maxs[-5:])

print('min(maxs) =', np.min(maxs), '   max(maxs) =', np.max(maxs))

mins = csv_data['最低気温'].values

print('mins =\n', mins[:5], mins[-5:])

print('min(mins) =', np.min(mins),'   max{mins) =', np.max(mins))

v_bins = np.arange(-15,31,5)

 

plt.figure(figsize = (5,7))              #   描画画面のサイズ、縦長

ax1 = plt.subplot(2, 1, 1)               #   描画画面を2行1列に区切った1番目の領域

ax1.set_title('最高気温', fontsize=20)

ax1.set_xlabel('', fontsize=16)

ax1.set_ylabel('度数', fontsize=16)

results1=ax1.hist(maxs, bins=v_bins, color = 'orange')

ax1.plot([], 's', c = 'orange', label = '最高気温')      #     空リストは何も表示しない

ax1.legend(fontsize = 16)

 

ax2 = plt.subplot(212, sharex = ax1)      #   描画画面を2行1列に区切った2番目の領域

ax2.set_title('最低気温', fontsize=20)

ax2.set_xlabel('', fontsize=16)

ax2.set_ylabel('度数', fontsize=16)

results2=ax2.hist(mins, bins = v_bins, color = 'cyan')

ax2.plot([], 's', c = 'cyan', label='最低気温')

plt.legend(fontsize=16)

plt.tight_layout()                         #   描画画面内に納まるように調整

plt.show()

print('results1 =\n', results1)

print('results2 =\n', results2)

 

 

次のスクリプトで、描画画面全体の大きさを設定している。

 

plt.figure(figsize = (5,7))

 

次のスクリプト

 

ax1 = plt.subplot(2, 1, 1)

 

は、画面を2行1列の領域に分け、1番目の領域の座標系をax1とするものである。描画領域は、左上から右方向に行単位で数え1から始まる自然数である。

次のスクリプトでは、画面を2行1列に分けて、2つ目の領域をax2で表すものである。

 

ax2 = plt.subplot(212, sharex = ax1)

 

パラメータsharex = ax1により、座標系ax2は座標系ax1X軸の座標が共通であると設定している。

 

グラフを横に並べた場合が、図H.6である。

H.6

 

H.6のグラフは、リストH.5のスクリプトで描かれている。

 

 

リストH.5 グラフを縦に並べた場合(two_hist_h.py

 

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import japanize_matplotlib              #   日本語表示用モジュール

 

with open('最高最低気温20231127.csv', 'r') as f:

    csv_data = pd.read_csv(f)           #   CSVファイルの読み込み

   

print('csv_data =\n', csv_data)

names = [v for v in csv_data.keys()]    #   キーのリスト

print('names =\n', names)

data = csv_data.values                  #    データのndarray

print('data =\n', data)

 

maxs = csv_data['最高気温'].values

print('maxs =\n', maxs[:5], maxs[-5:])

print('min(maxs) =', np.min(maxs), '   max(maxs) =', np.max(maxs))

mins = csv_data['最低気温'].values

print('mins =\n', mins[:5], mins[-5:])

print('min(mins) =', np.min(mins),'   max{mins) =', np.max(mins))

v_bins = np.arange(-15,31,5)

plt.figure(figsize = (7,5))

fig, (ax1, ax2) = plt.subplots(1,2, sharey=True)

fig.suptitle('20231127日の気温', fontsize=20)

ax1.set_title('最低気温', fontsize=18)

ax1.set_ylabel('', fontsize=16)

ax1.set_xlabel('度数', fontsize=16)

results2=ax1.hist(mins, bins = v_bins, orientation = 'horizontal',

                  color = 'cyan')

ax1.plot([], 's', c = 'cyan', label='最低気温')

ax1.legend(fontsize=16)

 

ax2.set_title('最高気温', fontsize=18)

ax2.set_xlabel('度数', fontsize=16)

results1=ax2.hist(maxs, bins=v_bins,

                  orientation = 'horizontal', color = 'orange')

ax2.plot([], 's', c = 'orange', label = '最高気温')

ax2.legend(fontsize = 16)

 

fig.tight_layout()

fig.show()

print('results1 =\n', results1)

print('results2 =\n', results2)

 

 

リストH.5では、次のスクリプトで描画画面を1行2列に分け、それぞれを座標系ax1ax2で表している。

 

fig, (ax1, ax2) = plt.subplots(1,2, sharey=True)

fig.suptitle('20231127日の気温', fontsize=20)

 

パラメタsharey=Trueの指定により、2つのグラフのY軸座標は共通である。

画面の図全体を表すfigsuptitleにより、図全体のタイトルが設定されている。

 

 

 

散布図

 

最高気温と最低気温のデータ(図H.1)の散布図を描いてみるために、リストS.1のスクリプトを用意した。

 

 

リストS.1 散布図描画の簡単なスクリプト(simple_scatter.py

 

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import japanize_matplotlib              #   日本語表示用モジュール

 

with open('最高最低気温20231127.csv', 'r') as f:

    csv_data = pd.read_csv(f)           #   CSVファイルの読み込み

 

maxs = csv_data['最高気温'].values

mins = csv_data['最低気温'].values

 

plt.scatter(mins, maxs)                 #   散布図の描画

plt.xlabel('最低気温', fontsize=16)

plt.ylabel('最高気温', fontsize=16)

plt.show()

 

 

リストS.1のスクリプトを実行すると、図S.1の散布図が描かれる。

S.1

 

散布図に、それぞれの変数、最低気温と最高気温、のヒストグラムも付け加えるために、リストS.2のスクリプトを作成した。

 

 

リストS.2 散布図とヒストグラムの描画(scatter_hist.py

 

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import japanize_matplotlib              #   日本語表示用モジュール

 

with open('最高最低気温20231127.csv', 'r') as f:

    csv_data = pd.read_csv(f)           #   CSVファイルの読み込み

 

maxs = csv_data['最高気温'].values

mins = csv_data['最低気温'].values

 

#      描画画面の作成

fig = plt.figure(figsize=(7,7))

 

#     描画画面を3行3列のグリッドとして、

#   0行目、0列目から2行1列の領域を、座標ax1とする

ax1 = plt.subplot2grid((3,3), (0,0), rowspan=2, colspan=1,)

 

#     描画画面を3行3列のグリッドとして、

#   0行目、1列目から2行2列の領域を、座標ax2とする

#     Y座標はax1と共通とする

ax2 = plt.subplot2grid((3,3), (0,1), rowspan=2, colspan=2, sharey=ax1)

 

#     描画画面を3行3列のグリッドとして、

#   2行目、1列目から1行2列の領域を、座標ax3とする

#     X座標はax2と共通とする

ax3 = plt.subplot2grid((3,3), (2,1), rowspan=1, colspan=2, sharex = ax2)

 

ax1.hist(maxs, orientation='horizontal', bins=np.arange(-5, 31, 5))

ax2.plot(mins, maxs, marker='o', linewidth=0, fillstyle='none')

ax2.set_xlabel('最低気温', fontsize=16)

ax2.set_ylabel('最高気温', fontsize=16)

ax3.hist(mins, bins=np.arange(-15, 26, 5))

 

fig.suptitle('最低気温と最高気温', fontsize=20)

fig.tight_layout()

fig.show()

 

 

リストS.2のスクリプトを実行すると、図S.2のグラフが描かれる。

S.2

 

S.2の散布図では、点は中空の丸で描かれている。中空のマーカーで描くために、関数scatterではなく、関数plotによる描画を行っている。

 

ax2.plot(mins, maxs, marker='o', linewidth=0, fillstyle='none')

 

マーカーとしてパラメータmarker='o'により丸を指定して、中空にするためにパラメータfillstyle='none'を設定している。点と点の間の線分の描画を避けるためにパラメータlinewidth=0を設定して線の太さを0としている。

画面の作成において、画面全体を表す変数figを用意している。

 

#      描画画面の作成

fig = plt.figure(figsize=(7,7))

 

この変数figを用いて、グラフ全体のタイトル、グラフの整列、グラフ表示を行っている。

 

fig.suptitle('最低気温と最高気温', fontsize=20)

fig.tight_layout()

fig.show()

 

 

Matplotlibのマーカーとカラー

 

PythonのモジュールMatplotlibには、グラフ描画関係の関数がいろいろ用意されている。ウェブサイト

 

https://matplotlib.org/3.5.3/api/_as_gen/matplotlib.pyplot.html

 

を参照されたい。

グラフ描画におけるマーカー、色などの設定のサンプルとして、図M.1を描いてみた。

M.1

 

スクリプトは、リストM.1に示すものである。

 

 

リストM.1 マーカー、色などの設定例(marker_color.py

 

import matplotlib.pyplot as plt

"""

           背景色が黒の描画画面の作成

"""

plt.figure(figsize=(7,7), facecolor='k')

"""

               座標内を青に設定

"""

ax = plt.axes()

ax.set_facecolor('b')

"""

          座標の枠を黄色の線で表示

       描画領域の基準位置として使用

"""

plt.plot([0,1,1,0,0], [0,0,1,1,0], 'y')

"""

            大きな白い円盤の表示

        色をRGB'#FFFFFF'で設定している

"""

plt.scatter(0.5, 0.7, marker='o', s=5000, c='#FFFFFF')

"""

        rcParamsによりマーカーの枠の色と枠の太さを設定

"""

plt.rc('lines', markeredgecolor='g', markeredgewidth=10)

"""

      2つの上向き三角形の点の描画

      linewidth=0と設定して2つの点の間の線分の描画を無効にしている

"""

plt.plot([0.25, 0.75], [0.2, 0.2], c='cyan', marker='^', markersize=100,

         linewidth=0)

"""

         rcParamsをデフォルト値に戻す

"""

plt.rcdefaults()

"""

                  星印の描画

"""

plt.scatter(0.5, 0.4, marker='*', s = 1000, c = 'orange')

plt.scatter([0.2, 0.8], [0.8, 0.8], marker='*', c='y', s=200)

"""

     茶色の太い線を引いてから、上から黒の点線を描画

"""

plt.plot([0,1],[0.01,0.01], c = 'saddlebrown', linewidth=20)

plt.plot([0,1],[0.01,0.01], c = 'k', linestyle=(0,(0.1,1)), linewidth=20)

plt.show()

 

 

 

Home