% matplotlib inline
これまで,出てきた関数(print(), input(), int(), list()などなど)は組み込み関数と呼ばれるものです.組み込み関数以外の特定の用途で使用する関数やメソッドをまとめたものをモジュールと呼び,複数のモジュールをまとめたものをパッケージ呼びます.ただし,モジュールとパッケージの区別は厳密ではありません.モジュールAの中にモジュールBが含まれている場合に,モジュールAをパッケージと呼んでいるだけです.Pythonでは標準で用意されているモジュールは標準ライブラリと呼ばれ,それらのモジュールを上手く使うことで比較的容易にプログラミングを実行できます(標準ライブラリ).また,Pythonでは標準ライブラリ以外にとても便利で高度な機能を持つパッケージが数多く用意されてます.それらのパッケージの大部分はPyPI(Python Package Index 左のボックスにPython3のパッケージリストがあります,ある"Browse packages"に必要なパッケージがあります)に登録されており,自由にインストールし使うことができます.実は皆さんのPCにはPythonをインストールした段階で科学技術計算に使用する多くのパッケージがインストールされています(PyPIから自由に必要なパッケージを取ってきて使用する方法はここでは説明しません).
(一部の)標準ライブラリの紹介
| モジュール名 | モジュールの機能 | (独断と偏見の)数理工学科学生のための重要度 | |
|---|---|---|---|
| re | 正規表現 | ○ | |
| math | 数学関数 | ×(より高機能なnumpyで代用) | |
| decimal | 10進固定及び浮動小数点数の算術演算 | ×(より高機能なnumpyで代用) | |
| random | 疑似乱数生成 | ×(より高機能なnumpyで代用) | |
| sys | システムパラメータ | △ | |
| os | osのインターフェース | ○ | |
| csv | csvファイルの読み書き | ×(より高機能なpandasで代用) |
便利で有名な拡張パッケージの紹介
| パッケージ名 | パッケージの機能 |
|---|---|
| numpy | 数値計算ライブラリ |
| matplotlib | (主に2D)グラフ作成ライブラリ |
| scipy | 科学技術計算ライブラリ(数値積分,線形代数演算,FFT,乱数etc) |
| pandas | 統計解析のフォーマット(フレームワーク)ライブラリ |
| statsmodels | 統計解析ライブラリ |
| sympy | 数式処理ライブラリ |
| scikit-learn | 機械学習ライブラリ |
| opencv | 画像処理ライブラリ |
| openGL | 2D,3Dコンピュータグラフィックス(動画など) |
| networkX | ネットワーク解析ライブラリ |
| kivy | マルチタッチアプリ開発ツールキットライブラリ |
| tensorflow | (Googleが満を期して出した)機械学習・人工知能ライブラリ(2016年度半ばからPythonにしか対応) |
ここでは幾つかの便利なパッケージを使いながらモジュールの使い方に慣れましょう.
mathモジュールを例に)¶数学関数などを扱うためのPythonの標準パッケージの中にmathモジュールがあります.ここではmathモジュールを例にモジュールの使い方を学びます.(実は,より強力な数値計算のための拡張パッケージとしてnumpyパッケージがあります.皆さんが将来卒研などに取り組む際にはmathを使わずnumpyを使うことになるでしょう.numpyマニュアル)
import math
print(math.radians(180)) # numpyパッケージのradians()関数を用いて引数"180"度をラジアン表現に変換する
上記プログラムは,下記の動作をします.
mathモジュールを読み込みmathモジュール内で定義されているradians()関数を用いて"180度"を$\pi$ラジアンへ変換するこのように,モジュールは
import モジュール名(パッケージ名)
で導入できます. そして,導入したモジュール内で定義されている関数は
モジュール名.関数( )
という形で使用できます.
また,モジュール名を記述せず関数を直接利用したい場合は
from モジュール名 import 関数名
とします.下記のプログラムは上のものと同じ結果を示します.
from math import radians
print(radians(180))
また,mathモジュールに含まれるすべての関数を直接利用した場合は下記のように記述します.
from math import *
print(radians(180))
print(exp(0))
ただし,上述のように関数名を直接用いる時には,同じ関数名をプログラム内で使用しないように注意してください.
関数名の重複を避けかつモジュール名を短く表現したい場合はas演算子を用います.
import math as mt
print(mt.radians(180))
print(mt.pi)
matplotlibパッケージを例に)¶matplotlibパッケージ(グラフ作成パッケージ)の中に含まれているpyplotモジュールを呼び出す方法は次のようにします.(matplotlibの使い方はすぐ後でやります)
import matplotlib.pyplot
x = list(range(0,10))
y = list(range(0,20, 2))
matplotlib.pyplot.plot(x, y)
matplotlib.pyplot.show()
上記のプログラムは下記を実行してます.
matplotlibパッケージ内で定義されているpyplotモジュールを読み込んでますxにリスト[0, 1, ・・・, 9]を代入yにリスト[0, 2, ・・・, 18]を代入このようにパッケージ内でさらにモジュールとしてまとめられている関数は
パッケージ名.モジュール名.関数( )
という形で呼び出すことができます(4,5行目は後で説明します).
モジュールと同様に"as"演算子を用いパッケージ+モジュール名を短くすることができる
import matplotlib.pyplot as plt # "matpotlib.pyplot"モジュールを"plt"という名前でインポート
x = list(range(0,10))
y = list(range(0,20, 2))
plt.plot(x, y) # matplotlib.pyplot.plot(x, y)を同じ意味
plt.show()
標準ライブラリの一つであるrandomモジュールには$[0, 1]$区間の一様乱数を返すrandom()関数が定義されてます.
randomモジュールからrandom()関数をインポートし,10個の乱数($[0, 1]$区間)を要素として持つリストを作成して下さい.matplotlibパッケージの使い方¶さて,上記のモジュールの使い方を学びましたのでここでは2次元グラフの表示できるパッケージmatplotlibの使い方を学びます.
科学技術計算においてデータ列を2次元や3次元のグラフにプロット場合や数式を2次元や3次元の空間に記述し視覚化することはとても大切です.matplotlibはPythonに導入された2次元、3次元グラフ作成の拡張パッケージです(マニュアルはここ).
順番に使い方を見てみましょう.まずは$y= \sin{x}$ $(0 \leq x \leq 2\pi)$の関数を出力します.
# sin関数の表示[0, 2pi) (このプログラムはスマートなプログラムではありません.分かり易さを重視してます)
import math
import matplotlib.pyplot as plt
x, y = [],[]
for i in range(0, 396, 18):
x.append([math.radians(i)])
y.append(math.sin(math.radians(i)))
plt.plot(x, y)
plt.show()
上記のプログラムは下記を実行してます.
mathパッケージを読み込みmatplotlibパッケージ内で定義されているpyplotモジュールを読み込んでいますx, yを準備mathパッケージのradians()関数を用いてiをラジアンに変換し,リストxへ付け加えるx[i]をsin関数の引数としリストyへ付け加える(要するに$y_i=\sin{x_i}$)とは言え、分かり易さを優先し以下ではforループを用いて書きます。
# X軸、Y軸の表示
import math
import matplotlib.pyplot as plt
x, y = [],[]
for i in range(0, 396, 18):
x.append([math.radians(i)])
y.append(math.sin(math.radians(i)))
plt.plot(x, y)
plt.xlabel("X", fontsize=20) # x軸に"X-axis"という名前を付けフォントサイズを20にする(このままでは日本語は使えません)
plt.ylabel("Y", fontsize=20) # y軸に"Y-axis"という名前を付けフォントサイズを20にする(このままでは日本語は使えません)
plt.show()
# X軸、Y軸の表示範囲の設定
import math
import matplotlib.pyplot as plt
x, y = [],[]
for i in range(0, 396, 18):
x.append([math.radians(i)])
y.append(math.sin(math.radians(i)))
plt.plot(x, y)
v = [0, 2*math.pi, -1, 1] # x,y軸の範囲指定するためのリストv=[x_min, x_max, y_min, y_max]を用意
plt.axis(v) # 軸の設定を行う
plt.xlabel("X", fontsize=20)
plt.ylabel("Y", fontsize=20)
plt.show()
# X軸とY軸のスケールを一致させる
import math
import matplotlib.pyplot as plt
x, y = [],[]
for i in range(0, 396, 18):
x.append([math.radians(i)])
y.append(math.sin(math.radians(i)))
plt.plot(x, y)
plt.axis("scaled") # X軸とY軸のスケールを一致させる
v = [0, 2*math.pi, -1, 1]
plt.axis(v)
plt.xlabel("X", fontsize=20)
plt.ylabel("Y", fontsize=20)
plt.show()
# cos関数も同時に表示し,凡例を加える
import math
import matplotlib.pyplot as plt
x, y, z = [], [], [] # cos関数の値を代入するリストzを用意
for i in range(0, 396, 18):
x.append([math.radians(i)])
y.append(math.sin(math.radians(i)))
z.append(math.cos(math.radians(i))) # ラジアンに変換したx[i]をcos関数の引数としリストzへ付け加える(要するに$z_i=\cos{x_i}$)
plt.plot(x, y, label="$y=\sin{x}$") # y=sinxに凡例を付ける
plt.plot(x, z, label="$y=\cos{x}$") # y=cosxに凡例を付ける
plt.axis("scaled")
v = [0, 2*math.pi, -1, 1]
plt.axis(v)
plt.xlabel("X", fontsize=20)
plt.ylabel("Y", fontsize=20)
plt.legend() # 凡例を表示
plt.show()
# 線の色と太さの変更
import math
import matplotlib.pyplot as plt
x, y, z = [], [], []
for i in range(0, 396, 18):
x.append([math.radians(i)])
y.append(math.sin(math.radians(i)))
z.append(math.cos(math.radians(i)))
plt.plot(x, y, color="r", linewidth=4, label="$y=\sin{x}$") # 線の色をredに,線の太さを4にする
plt.plot(x, z, color="k", linewidth=2, label="$y=\cos{x}$") # 線の色をblackに,線の太さを2にする
plt.axis("scaled")
v = [0, 2*math.pi, -1, 1]
plt.axis(v)
plt.xlabel("X", fontsize=20)
plt.ylabel("Y", fontsize=20)
plt.legend()
plt.show()
# マーカーや線種の指定
import math
import matplotlib.pyplot as plt
x, y, z = [], [], []
for i in range(0, 396, 18):
x.append([math.radians(i)])
y.append(math.sin(math.radians(i)))
z.append(math.cos(math.radians(i)))
plt.plot(x, y, color="r", marker="o", linestyle="-", label="$y=\sin{x}$") # 色をred,マーカー形を"o",線種を"-"と指定した
plt.plot(x, z, color="k", marker="d", linestyle="", label="$y=\cos{x}$") # 色をblack, マーカー形を"d", 線種をなしと指定した
plt.axis("scaled")
v = [0, 2*math.pi, -1, 1]
plt.axis(v)
plt.xlabel("X", fontsize=20)
plt.ylabel("Y", fontsize=20)
plt.legend()
plt.show()
# マーカーや線種の指定 簡略化
import math
import matplotlib.pyplot as plt
x, y, z = [], [], []
for i in range(0, 396, 18):
x.append([math.radians(i)])
y.append(math.sin(math.radians(i)))
z.append(math.cos(math.radians(i)))
plt.plot(x, y, "ro-", label="$y=\sin{x}$")
plt.plot(x, z, "kd", label="$y=\cos{x}$")
plt.axis("scaled")
v = [0, 2*math.pi, -1, 1]
plt.axis(v)
plt.xlabel("X", fontsize=20)
plt.ylabel("Y", fontsize=20)
plt.legend()
plt.show()
# グラフ画像の出力
import math
import matplotlib.pyplot as plt
x, y, z = [], [], []
for i in range(0, 396, 18):
x.append([math.radians(i)])
y.append(math.sin(math.radians(i)))
z.append(math.cos(math.radians(i)))
plt.plot(x, y, "ro-", label="$y=\sin{x}$")
plt.plot(x, z, "kd", label="$y=\cos{x}$")
plt.axis("scaled")
v = [0, 2*math.pi, -1, 1]
plt.axis(v)
plt.xlabel("X", fontsize=20)
plt.ylabel("Y", fontsize=20)
plt.legend()
plt.savefig("it06_fig1.pdf") # 画像pdfとして出力・保存する
# 複数グラフの表示
import math
import matplotlib.pyplot as plt
x, y, z = [], [], []
for i in range(0, 396, 18):
x.append([math.radians(i)])
y.append(math.sin(math.radians(i)))
z.append(math.cos(math.radians(i)))
plt.subplot(2, 1, 1) # 画面を2行1列に分割し1(上側)に出力するという事
plt.plot(x, y, "ro", label="$y=\sin{x}$")
plt.axis("scaled")
v = [0, 2*math.pi, -1, 1]
plt.axis(v)
plt.xlabel("X-axis", fontsize=20)
plt.ylabel("Y-axis", fontsize=20)
plt.legend()
plt.subplot(2, 1, 2) # 画面を2行1列に分割し2(下側)に出力するという事
plt.plot(x, z, "kd", label="$y=\cos{x}$")
plt.axis("scaled")
v = [0, 2*math.pi, -1, 1]
plt.axis(v)
plt.xlabel("X", fontsize=20)
plt.ylabel("Y", fontsize=20)
plt.legend()
plt.show()
各自それぞれ自分の好きな関数を2つ用意し上述のように複数グラフを作成して下さい.軸の範囲,軸のラベル,凡例,プロットの色など工夫して見やすくして下さい.
# このプログラムはスマートではありません(皆さんが今持っている知識のみで作ってます)
import matplotlib.pyplot as plt
year = 2015
in_file1 = open("I101_{}.csv".format(year), "r", encoding='shift-jis')
list1, v_fin, v_max, v_min, v_date =[], [], [], [], []
i=0
for line in in_file1:
if i > 1 :
line = line.replace("\n", "") # "\n"を削除
list1.append(line.split(",")) # ","で分割
v_fin.append(float(list1[i-2][3])) # 株価の終値データをfloat型に変換し,
v_date.append(i-2) # x軸としてデータの順番を用いる(年月日を軸にするためにはdatetimeモジュールを使う必要あり)
i += 1
in_file1.close()
v_fin.reverse() # 株価の終値データを古い順にする
plt.subplot(2, 1, 1)
plt.plot(v_date, v_fin, "g-")
plt.title("INDEX NIKKEI {}".format(year))
# 前日の株価との差を取ってみる
dif_fin, dif_date = [], []
for i in range(1, len(v_fin)):
dif_fin.append(v_fin[i] - v_fin[i-1])
dif_date.append(i-1)
plt.subplot(2, 1, 2)
plt.plot(dif_date, dif_fin, "b-")
plt.title("The difference between the stock price of every other day(DST)")
plt.tight_layout()
plt.show()
# 前日との株価の差の分布は?
plt.hist(dif_fin, bins=20, range = (-1000, 1000))
plt.title("Histgram of DST")
plt.xlabel("Price Difference")
plt.show()
matplotlibは動的なアニメーションを作ることもできます。そして、それをJupyter Notebook上で埋め込んで表示しさらに.mp4形式で保存することもできます。ただ、私がイロイロ試した範囲ではIPython、matplotlib、Jupyter Notebookのバージョン依存で上手く動かないもしくは表示されたい場合があります。以下の手法ではおそらく皆さんの環境下で動作すると思っておりますが、動かなかったらドンマイ(2017/11/09)。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation, rc
from IPython.display import HTML #Jupyter notebookでアニメ表示するには現在ではこれが重要
fig, ax = plt.subplots()
ax.set_xlim(( 0, 2))
ax.set_ylim((-2, 2))
line, = ax.plot([], [], lw=2) #空のデータ(x, y)を用意する line,はタプル
plt.close()
def init():
line.set_data([], [])
return (line,) #
def animate(i):
x=np.linspace(0, 2, 1000)
y=np.sin(2*np.pi*(x-0.01*i))
line.set_data(x, y)
return (line,)
rc('animation', html='html5')
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=20, blit=True)
anim