メインコンテンツへスキップ
  1. 第01講 プログラミングAの復習/

グラフ出力

Matplotlib
目次

ヒストグラム
#

教科書 p.341 (Lesson 12)

score.dat を読み込み,ヒストグラムを出力するプログラム histogram1.py を作成します. score.datには,とある講義の成績です. 各行には学生の得点(0〜100)のみが記載されています. 各行のデータを読み取り,ヒストグラムを出力しましょう.

📥 score.datのダウンロード

import matplotlib.pyplot as plt # ヒストグラムを描画するライブラリをインポートする.
import sys

data = []
f = open(sys.argv[1], 'r') # ファイルを読み込む.
for line in f.readlines(): # ファイルの各行に対して繰り返す.
    data.append(int(line)) # 各行のデータを整数に変換してリストに追加する.
f.close()                  # ファイルを閉じる.

plt.hist(data, bins=20)    # ビン(棒)数を20に設定してヒストグラムを描画する.
plt.title("bins=20")       # グラフのタイトルを設定する.
plt.show()                 # ヒストグラムを表示する.

実行例
#

ヒストグラム(binsを更新)

散布図
#

モンテカルロ法で \(\pi\)を求めるプログラム monte_carlo_pi.py を作成します. モンテカルロ法とは,乱数を用いて確率的に解を求める方法です.

0〜1の範囲の2つの変数 xyを求めます. \((x, y)\)の原点からの距離\(d\)を求め,\(d \leq 1\)のとき,その点は半径1の円の内部にあると判定します. この判定を\(n\)回繰り返し,半径1の円の内部に含まれる点の数を数えます. 円の内部に含まれる数は確率的に\(\frac{\pi}{4}\)になるので, この数を\(n\)で割り,4倍することで円の面積を求めます.

モンテカルロ法による\(\pi\)の計算

0〜1の乱数を発生させるにはrandomモジュールをインポートし,random.random()関数を用います. また,(x, y) の原点からの距離は,\(\sqrt{x^2 + y^2}\)ですので,mathモジュールをインポートし,math.sqrt()関数を用います.

import random
import math

hit = 0
n = 10000
for i in range(n):
    x = random.random()
    y = random.random()
    if math.sqrt(x*x + y*y) <= 1:
        hit = hit + 1
print(4 * hit / n)

このとき,半径1の円の内部に含まれる点と外部に含まれる点を散布図で描画します. ヒットした場合(円の内部にある場合)は赤,ヒットしなかった場合(円の外部にある場合)は青で描画します. それぞれの x座標,y座標を格納するリストを用意し,ヒットすれば赤のリストに,ヒットしなければ青のリストに追加します. 最後に,matplotlibを用いて散布図を描画します. デフォルトでは,グラフの大きさは横長になるため,plt.figure(figsize=(6, 6))で正方形に設定します.

import random
import math
import matplotlib.pyplot as plt

hit = 0
n = 10000
red_x = []  # ヒットした点のx座標を格納するリスト
red_y = []  # ヒットした点のy座標を格納するリスト
blue_x = [] # ヒットしなかった点のx座標を格納するリスト
blue_y = [] # ヒットしなかった点のy座標を格納するリスト
for i in range(n):
    x = random.random()
    y = random.random()
    if math.sqrt(x*x + y*y) <= 1:
        hit = hit + 1
        red_x.append(x)
        red_y.append(y)
    else:
        blue_x.append(x)
        blue_y.append(y)

pi = 4 * hit / n
print("pi = ", pi)

plt.figure(figsize=(6, 6)) # グラフの大きさを正方形に設定する.
plt.title(f"Monte Carlo Simulation (pi={pi}, n={n})")
plt.scatter(red_x, red_y, color='red', s=1)    # ヒットした点を赤でプロットする.
plt.scatter(blue_x, blue_y, color='blue', s=1) # ヒットしなかった点を青でプロットする.
plt.show()

実行結果は必ずしも以下の通りになりませんが,\(n\)を増加させると円周率に近付いていくことが期待されます.

モンテカルロ法による\(\pi\)