ラベル matplotlib の投稿を表示しています。 すべての投稿を表示
ラベル matplotlib の投稿を表示しています。 すべての投稿を表示

2017年9月20日水曜日

グラフのタイトル・ラベル・補助線を表示する

前回のグラフにタイトルやラベルを表示する。タイトルは matplotlib.pyplot.title関数、ラベルは matplotlib.pyplot.xlabel 関数(x軸のラベル)、matplotlib.pyplot.xlabel 関数(y軸のラベル)を使用する。
なお、表示データは前回のものを使用する。
import matplotlib.pyplot as plt

plt.title("The Population of Italy")
plt.xlabel("YEAR")
plt.ylabel("Thousand unit", fontproperties=fp)
plt.plot(x, y)
plt.show()
また、補助線を表示したい場合は、matplotlib.pyplot.grid関数の引数に True を与えればよい。
plt.grid(True)

2017年9月13日水曜日

Python で折れ線グラフを作成する

matplotlib を利用して、折れ線グラフを作成してみる。折れ線グラフは、matplotlib.pylot.pyplot 関数を使用して作成する。
matplotlib.pylot.plot 関数は、表示する関数を $y=f(x)$ とした場合、第1引数に $x$ 軸のリスト、第2引数に $y=f(x)$のリストを与えると、該当関数のグラフを表示する。
plt.plot(x, y)
以下例では、表示するデータとして 1990年から2010年までのイタリアの人口データを利用している。
import numpy as np
import matplotlib.pyplot as plt

italy_population = [
    ["1990", 56719],
    ["1991", 56759],
    ["1992", 56797],
    ["1993", 56832],
    ["1994", 56843],
    ["1995", 56844],
    ["1996", 56860],
    ["1997", 56890],
    ["1998", 56907],
    ["1999", 56916],
    ["2000", 56942],
    ["2001", 56974],
    ["2002", 57059],
    ["2003", 57313],
    ["2004", 57685],
    ["2005", 57969],
    ["2006", 58144],
    ["2007", 58438],
    ["2008", 58827],
    ["2009", 59095],
    ["2010", 59277],
    ]
x = []
y = []

for data in italy_population:
    x.append(data[0])
    y.append(data[1])
x = np.array(x)
y = np.array(y)
plt.plot(x, y)
plt.show()

2017年5月7日日曜日

matplotlib.pyplot.hist 関数の normed パラメータ

matplotlib.pyplot.hist 関数には、normed パラメータがある。
このパラメータの説明として「bin の頻度の合計が 1 になる」といったものが散見されるが、正確には「bin の面積が 1 になる」である。
from matplotlib import pyplot as plt

data = [1, 1, 2, 2, 2, 3, 4, 5]
n, bins, _ = plt.hist(data, bins=[1, 2, 3, 4, 5, 6], align="left", rwidth=0.8,
                      normed=True, alpha=0.5, color="red")
plt.grid(True)
plt.show()
matplotlib.pyplot.hist 関数の戻り値 3つのうち、1つ目には各 bin の値がリスト形式で格納される。この値を合計してみる。
>> print(sum(n))

1.0
この例の場合「bin の頻度の合計が 1 になる」は正しい。ここで data と bin をそれぞれ 1/10 にしてみる。
>> data = [0.1, 0.1, 0.2, 0.2, 0.2, 0.3, 0.4, 0.5]
>> n, bins, _ = plt.hist(data, bins=[0.1, 0.2, 0.3, 0.4, 0.5, 0.6], align="left", rwidth=0.8,
>>                       normed=True, alpha=0.5, color="red")
>> print(n)
>> print(sum(n))


[ 2.5   3.75  1.25  1.25  1.25]
10.0
matplotlib.pyplot.hist 関数の 2つ目の戻り値は bin の値をそのまま返す。そこで、各 bin の長さを測定する。
>> import numpy
>>
>> print(np.diff(bins))

[ 0.1  0.1  0.1  0.1  0.1]
各 bin の値に対して上で取得した長さを乗算し、bin の面積を合計する。
>> print(np.sum(n * np.diff(bins)))

1.0

2017年5月6日土曜日

Python ヒストグラムを作成する(2)

6面ダイスの場合、「6」の出る確率は理論上 1/6 であるが、実際に振ってみると出てくる数字に偏りがある。
前回の ThrowDice 関数を用いて、10 回投げてみる。
>> print(ThrowDice(6, 10))

[4 5 2 2 3 5 2 6 2 6]

>> print(ThrowDice(6, 19))

[3 5 4 2 2 4 2 5 4 1]
1回目の確率は 0.2 であるが、2 回目の確率は 0 である。投げる回数が多くなれば、1/6 に近づくか?
1000回投げた場合、理論上の値 1/6 には近づくが、多くの場合 1/6 にはならない。
>> x = ThrowDice(6, 1000)
>> print(1/6)
>> print(x[x == 6].size / x.size)

0.16666666666666666
0.177

>> x = ThrowDice(6, 1000)
>> print(1/6)
>> print(x[x == 6].size / x.size)

0.16666666666666666
0.153
1万回ダイスを振って「6」が出た確率を計算し、これを1万回繰り返した場合の確率の分布をヒストグラムで可視化する。
def getRatioList(dice, value, cnt1, cnt2):
    l = []
    for _ in range(cnt1):
        result = ThrowDice(dice, cnt2)
        r = (result[result == value]).size / result.size
        l.append(r)

    return l


l = getRatioList(6, 6, 10000, 10000)
plt.hist(l, align="mid", rwidth=0.5)
plt.grid(True)
plt.show()
1/6 = 0.166… 近辺が最も多くなっているが、0.175 や 0.160 にも値が出ている。より分かりやすくするため、y軸を割合に変更する。
なお、ダイスを振り直ししているため、表示されるグラフの形状が上のグラフと異なっている。
l = getRatioList(6, 6, 10000, 10000)
weight = np.ones_like(l)/len(l)
plt.hist(l, align="mid", rwidth=0.5, weights=weight)
plt.grid(True)
plt.show()
matplotlib.pyplot.hist 関数の weights パラメータは、グラフ上の値を weights パラメータで与えられたリストの各項で乗算する。上記例の場合は、ヒストグラムの各 bin の値に対して全体要素数の逆数を乗算し、当該binの全体に占める割合を算出している。
およそ 30% の割合で 6 回に 1 回の確率で「6」が出るが、10 % 程度の確率で 1/0.16 = 6.25 回振らないと「6」が出ない。
より分かりやすいように comulative パラメータを True に変更し、累積ヒストグラムを作成する。
…
plt.hist(l, align="left", bins=10, rwidth=0.5, weights=weight,
         cumulative=True)
…

例えば、携帯ゲームでレアカードの出現率が 1% (すなわち理論上 100 回に 1 回出現する)とする。100 回チャレンジを1万回繰り返した結果が以下の通りである。
100 回やっても全く該当カードが入手できない確率が 35% 以上もあることがわかる。

2017年5月5日金曜日

Python でヒストグラムを作成する

通常の6面ダイスの場合、各面が出る確率は同じであるため、ダイスを投げる行為を乱数を使用して表す。
引数 num はダイスの面数、times で投げる回数を与えることにする。戻り値は、1 から 6 までの numpy.array 型となる。
import numpy as np
import matplotlib.pyplot as plt

def ThrowDice(num, times):
    return np.random.randint(1, num+1, times)
試しに 6面ダイスを 10 回投げてみる。
>> print(ThrowDice(6, 10))

[1 5 4 2 2 5 6 1 1 6]
6面ダイスを100回投げて、各々の面に対して出た回数をグラフ化する。

ヒストグラムを生成する場合は、matplotlib.pyplot.hist 関数を使用する。
このとき、第1引数には表示したいデータリスト、引数 bins には対象となる値(1 ~6)および +1 した値(7)のリストを渡す。
また、引数 rwidth は、棒グラフの幅を示し、align は表示場所を表す。("left" の場合は、棒グラフの中央が bins で指定した値の真上になる。"mid" の場合は bins の中間位置、"right" の場合は棒グラフの中央が次のx値の真上になる。)
def showHistogram(bins, cnt):
    result = ThrowDice(6, cnt)
    print(result)
    plt.hist(result,
             align="left",
             rwidth=0.5,
             bins=bins)
    plt.grid(True)
    plt.show()

showHistogram([1, 2, 3, 4, 5, 6, 7], 100)

ここで bins=[1, 2, 3] としてみる。以下の例の場合、2 の目が出なかったがグラフ上には 2 回出たように表示される。
>>  showHistogram([1, 2, 3], 10)

[3 6 6 4 6 6 3 6 1 6]
一般的に bin にリスト [x_1, x_2, ・・・. x_n] が与えられた場合、半開区間 [x_1, x_2), [x_2, x_3), …, [x_n-2, x_n-1) および 閉区間 [x_n-1, x_n] が各binの区間となる。
この例の場合、半開区間 [1, 2), 閉区間[2, 3]に含まれる要素の数となるため、2つめの区間 [2, 3] には要素 3 が含まれ、その数は 2 となる。