まずはインポート
import numpy as np
import matplotlib.pyplot as plt
# 軸の名前などに日本語が使用可能
plt.rcParams["font.family"] = "MS Gothic"
グラフの基本
# 描画領域の確保
fig = plt.figure()
# 軸の確保
# 1つだけのグラフであれば1,1,1で問題ない
# 複数のグラフを並べるときにこの数字は変わるが、それについては後述
ax = fig.add_subplot(1, 1, 1)
# 軸に折れ線グラフを描く
# 折れ線グラフはplotで、散布図 (線なし) はscatter
# ただしplotで散布図を描くこともできる
ax.plot(np.array([1, 4, 7]), np.array([2, 5, 1])) # (1,2),(4,5),(7,1)を繋ぐ折れ線グラフ
# グラフの描画
plt.show()
点を打つ
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
# markerオプションで指定した座標に点を打つことができる
# marker = "o" : 丸い点
# marker = "x" : バツ印
# marker = "^" : 三角形
ax.plot(np.array([1, 4, 7]), np.array([2, 5, 1]), marker = "o")
plt.show()
線種の変更
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
# linestyleオプションで線種の変更ができる
# linestyle = "dashed" : 破線
# linestyle = "dotted" : 点線
# linestyle = "dashdot" : 一点鎖線
# linestyle = "none" : 線なし (markerと組み合わせると散布図ができる)
ax.plot(x, np.sin(x), linestyle = "dashed")
plt.show()
色を変える
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
# colorオプションで色の変更ができる (点の色も同時に変わる)
# color = "red"
# color = "tab:red" : 柔らかめの赤
# color = "black"
ax.plot(x, np.sin(x), color = "tab:green")
plt.show()
軸に名前を付ける
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
# ax.set_xlabelでx軸に名前が付く
ax.set_xlabel("x軸の名前")
# ax.set_ylabelでy軸に名前が付く
ax.set_ylabel("y軸の名前")
ax.plot(x, np.sin(x))
plt.show()
グラフに名前を付ける
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
# ax.set_titleでグラフに名前が付く
ax.set_title("sin(x)のグラフ")
ax.plot(x, np.sin(x))
plt.show()
軸の範囲を設定する
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
# ax.set_xlimでx軸の範囲を変えられる
ax.set_xlim(0, np.pi)
# ax.set_ylimでy軸の範囲を変えられる
ax.set_ylim(-5, 5)
ax.plot(x, np.tan(x))
plt.show()
軸の数値を設定する
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
# ax.set_xticks (ベクトル) でx軸の数値を好きな部分だけ表示できる
ax.set_xticks(np.array([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi]))
# ax.set_yticks (ベクトル) でy軸の数値を好きな部分だけ表示できる
ax.set_yticks(np.array([-1, -0.5, 0, 0.5, 1]))
ax.plot(x, np.sin(x))
plt.show()
軸の数値を設定し、好きな表記にする
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
ax.set_xticks(np.array([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi]))
# ax.set_xticklabels (ベクトル) で、xticksで設定した数値の表示を変えることができる
# ax.set_xticksとax.set_xtickslabelsのベクトルの要素数は同じでなければならない
ax.set_xticklabels(np.array(["0", "π/2", "π", "3π/2", "2π"]))
ax.set_yticks(np.array([-1, 0, 1]))
# ax.set_yticklabels (ベクトル) で、yticksで設定した数値の表示を変えることができる
# ax.set_yticksとax.set_ytickslabelsのベクトルの要素数は同じでなければならない
ax.set_yticklabels(np.array(["ymin", "0", "ymax"]))
ax.plot(x, np.sin(x))
plt.show()
目盛りに対してグリッドを付ける
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
ax.set_xticks(np.array([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi]))
ax.set_xticklabels(np.array(["0", "π/2", "π", "3π/2", "2π"]))
# ax.set_grid (axis = "x") で、x軸の目盛りに対してグリッドが付く。
ax.grid(axis = "x")
ax.set_yticks(np.array([-1, 0, 1]))
ax.set_yticklabels(np.array(["ymin", "0", "ymax"]))
# ax.set_grid (axis = "y") で、y軸の目盛りに対してグリッドが付く。
ax.grid(axis = "y", color="tab:red", linestyle = "dashed")
ax.plot(x, np.sin(x))
plt.show()
数値の付かない小目盛りを付ける
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
ax.set_xticks(np.array([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi]))
ax.set_xticklabels(np.array(["0", "π/2", "π", "3π/2", "2π"]))
# minor = Trueオプションで小目盛りの設定になる
ax.set_xticks(np.array([np.pi/4, 3*np.pi/4, 5*np.pi/4, 7*np.pi/4]), minor = True)
ax.set_yticks(np.array([-1, 0, 1]))
ax.set_yticklabels(np.array(["ymin", "0", "ymax"]))
ax.plot(x, np.sin(x))
plt.show()
小目盛りに対するグリッドを付ける
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
ax.set_xticks(np.array([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi]))
ax.set_xticklabels(np.array(["0", "π/2", "π", "3π/2", "2π"]))
ax.set_xticks(np.array([np.pi/4, 3*np.pi/4, 5*np.pi/4, 7*np.pi/4]), minor = True)
ax.grid(axis = "x")
# which = "minor"オプションで小目盛りに対するグリッドになる
ax.grid(axis = "x", which = "minor", linestyle = "dashed")
ax.set_yticks(np.array([-1, 0, 1]))
ax.set_yticklabels(np.array(["ymin", "0", "ymax"]))
ax.plot(x, np.sin(x))
plt.show()
x軸とy軸の長さと数値の割合を同じにする
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
# ax.set_aspect(1)で、縦と横の数値の比率が同じになる
ax.set_aspect(1)
ax.plot(x, np.sin(x))
plt.show()
文字列にLaTeXを用いる
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
# 文字列の""の前にrを付けることによりLaTeXの表記が使えるようになる
# ax.set_x(y)label, ax.set_title, ax.set_x(y)ticklabels, label (後述) 等が対応する
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$\sin(x)$")
ax.set_title(r"$\sin(x)$のグラフ")
ax.set_xticks(np.array([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi]))
ax.set_xticklabels(np.array(["0", r"$\pi/2$", r"$\pi$", r"$3\pi/2$", r"$2\pi$"]))
ax.set_yticks(np.array([-1, 0, 1]))
ax.set_yticklabels(np.array([r"$y_\mathrm{min}$", "0", r"$y_\mathrm{max}$"]))
ax.plot(x, np.sin(x))
plt.show()
グラフのサイズ
# figsizeオプションで描画領域のサイズを変えることができる
# デフォルトは[6.4; 4.8]
fig = plt.figure(figsize = np.array([6.4, 4.8]) * 0.75)
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
ax.plot(x, np.sin(x))
plt.show()
グラフの保存
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
ax.plot(x, np.sin(x))
# show()の代わりにsavefig("ファイル名")とすればグラフの保存ができる
# オプションでbbox_inches = "tight", pad_inches = 0.1とすれば周囲の余計な余白を極力小さくできる
# よく使う拡張子としてpngとpdfがある (拡張子で保存するファイルタイプを自動的に判断してくれる)
plt.savefig("graph.png", bbox_inches = "tight", pad_inches = 0.1)
1つの軸に複数のグラフを描画する
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
# ax.plotやax.scatterを繰り返し使うことで1つの軸に複数のグラフを描画できる
# 色は自動で変わる (勿論colorオプションで1つずつ指定できる)
ax.plot(x, np.sin(x))
ax.plot(x, np.cos(x))
plt.show()
plotとscatterの混在
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x1 = np.linspace(0, 2*np.pi, 100)
x2 = np.linspace(0, 2*np.pi, 10)
# ax.plotとax.scatterを混在させることもできる
# 色の管理はplotとscatterで別なので注意
ax.plot(x1, np.sin(x1))
ax.scatter(x2, np.cos(x2))
plt.show()
凡例の表示
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = np.linspace(0, 2*np.pi, 100)
# labelオプションで名前を付ける
ax.plot(x, np.sin(x), label = r"$\sin(x)$")
ax.plot(x, np.cos(x), label = r"$\cos(x)$")
# ax.legend()で、labelオプションで付けた名前を凡例として表示できる
ax.legend()
plt.show()
凡例の位置
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
x = np.linspace(0, 2*np.pi, 100)
ax.plot(x, np.sin(x), label = r"$\sin(x)$")
ax.plot(x, np.sin(x - 2*np.pi/5), label = r"$\sin(x-2\pi/5)$")
ax.plot(x, np.sin(x - 4*np.pi/5), label = r"$\sin(x-4\pi/5)$")
ax.plot(x, np.sin(x - 6*np.pi/5), label = r"$\sin(x-6\pi/5)$")
ax.plot(x, np.sin(x - 8*np.pi/5), label = r"$\sin(x-8\pi/5)$")
# 凡例の位置は自動で調節してくれるが、locで大まかな位置を指定できる
# 左上 "upper left"
# 中央上 "upper center"
# 右上 "upper right"
# 左中央 "center left"
# 中央 "center"
# 右中央 "center right"
# 左下 "lower left"
# 中央下 "lower center"
# 右下 "lower right"
ax.legend(loc = "center")
plt.show()
凡例の詳細位置
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
x = np.linspace(0, 2*np.pi, 100)
ax.plot(x, np.sin(x), label = r"$\sin(x)$")
ax.plot(x, np.sin(x - 2*np.pi/5), label = r"$\sin(x-2\pi/5)$")
ax.plot(x, np.sin(x - 4*np.pi/5), label = r"$\sin(x-4\pi/5)$")
ax.plot(x, np.sin(x - 6*np.pi/5), label = r"$\sin(x-6\pi/5)$")
ax.plot(x, np.sin(x - 8*np.pi/5), label = r"$\sin(x-8\pi/5)$")
# bbox_to_anchorで位置を指定できる。(0,0)が左下、(1,1)が右上
# さらにlocを指定すると凡例の位置をbbox_to_anchorに設定できる
# ncolsで列数を指定できる
ax.legend(bbox_to_anchor = (0.5, 1), loc = "lower center", ncols = 5)
plt.show()
左右に異なるy軸
fig = plt.figure()
t = np.linspace(0, 0.9, 100)
# まずは左側 (通常) のy軸に対するグラフを作成する
ax1 = fig.add_subplot(1, 1, 1)
ax1.plot(t, 5 - 9.8 * t)
ax1.set_xlabel("時刻 [s]")
ax1.set_ylabel("速度 [m/s]")
# 右側のy軸に対するグラフを作成する
# twinxを用いて右側にy軸が来る軸の作成
ax2 = ax1.twinx()
# ax1とax2で色の管理が別なので注意
ax2.plot(t, - 4.9 * t ** 2 + 5 * t)
ax2.set_ylabel("高さ [m]")
plt.show()
左右に異なるy軸 (色、凡例の調整)
fig = plt.figure()
t = np.linspace(0, 0.9, 100)
ax1 = fig.add_subplot(1, 1, 1)
ax1.plot(t, 5 - 9.8 * t, label = "速度 (摩擦なし) ")
ax1.plot(t, 24.6 * np.exp(- t / 2) - 19.6, label = "速度 (摩擦あり) ")
ax1.set_xlabel("時刻 [s]")
ax1.set_ylabel("速度 [m/s]")
ax1.legend()
ax2 = ax1.twinx()
ax2.plot(t, - 4.9 * t ** 2 + 5 * t, label = "高さ (摩擦なし) ", color = "tab:green")
ax2.plot(t, 49.2 * (1 - np.exp(- t / 2)) - 19.6 * t, label = "高さ (摩擦あり) ", color = "tab:red")
ax2.set_ylabel("高さ [m]")
ax2.legend()
plt.show()
複数の軸
# 複数の軸を描画するので描画領域の大きさを必ず設定しておく
fig = plt.figure(figsize = np.array([6.4 * 2, 4.8 * 3]) * 0.8)
x1 = np.linspace(- np.pi, np.pi, 100)
x2 = np.linspace(-1, 1, 100)
x3 = np.linspace(-2, 2, 100)
x4 = np.linspace(1, 2, 100)
# 縦3行横2列に軸を並べたときの1つめ、という意味
ax = fig.add_subplot(3, 2, 1)
ax.plot(x1, np.sin(x1), label = r"$\sin(x)$")
ax.plot(x1, np.cos(x1), label = r"$\cos(x)$")
ax.plot(x1, np.tan(x1), label = r"$\tan(x)$")
ax.set_ylim(-1.5, 1.5)
ax.set_xlabel(r"$x$")
ax.set_title("三角関数のグラフ")
ax.legend()
# 縦3行横2列に軸を並べたときの2つめ、という意味
ax = fig.add_subplot(3, 2, 2)
ax.plot(x3, np.sinh(x3), label = r"$\sinh(x)$")
ax.plot(x3, np.cosh(x3), label = r"$\cosh(x)$")
ax.plot(x3, np.tanh(x3), label = r"$\tanh(x)$")
ax.set_xlabel(r"$x$")
ax.set_title("双曲線関数のグラフ")
ax.legend()
# 縦3行横2列に軸を並べたときの3つめ、という意味
ax = fig.add_subplot(3, 2, 3)
ax.plot(x1, 1 / np.sin(x1), label = r"$\csc(x)$")
ax.plot(x1, 1 / np.cos(x1), label = r"$\sec(x)$")
ax.plot(x1, 1 / np.tan(x1), label = r"$\cot(x)$")
ax.set_ylim(-10, 10)
ax.set_xlabel(r"$x$")
ax.set_title("三角関数の逆数のグラフ")
ax.legend()
# 縦3行横2列に軸を並べたときの4つめ、という意味
ax = fig.add_subplot(3, 2, 4)
ax.plot(x3, 1 / np.sinh(x3), label = r"$\mathrm{csch}(x)$")
ax.plot(x3, 1 / np.cosh(x3), label = r"$\mathrm{sech}(x)$")
ax.plot(x3, 1 / np.tanh(x3), label = r"$\coth(x)$")
ax.set_ylim(-4, 4)
ax.set_xlabel(r"$x$")
ax.set_title("双曲線関数の逆数のグラフ")
ax.legend()
# 縦3行横2列に軸を並べたときの5つめ、という意味
ax = fig.add_subplot(3, 2, 5)
ax.plot(x2, np.arcsin(x2), label = r"$\sin^{-1}(x)$")
ax.plot(x2, np.arccos(x2), label = r"$\cos^{-1}(x)$")
ax.plot(x3, np.arctan(x3), label = r"$\tan^{-1}(x)$")
ax.set_xlabel(r"$x$")
ax.set_title("逆三角関数のグラフ")
ax.legend()
# 縦3行横2列に軸を並べたときの6つめ、という意味
ax = fig.add_subplot(3, 2, 6)
ax.plot(x3, np.arcsinh(x3), label = r"$\sinh^{-1}(x)$")
ax.plot(x4, np.arccosh(x4), label = r"$\cosh^{-1}(x)$")
ax.plot(x2, np.arctanh(x2), label = r"$\tanh^{-1}(x)$")
ax.set_xlabel(r"$x$")
ax.set_title("逆双曲線関数のグラフ")
ax.legend()
# subplots_adjustで軸の間隔を調整
# wspaceが横方向、hspaceが縦方向
plt.subplots_adjust(wspace=0.2, hspace=0.3)
plt.show()
片対数グラフ
fig = plt.figure()
x = np.linspace(0, 5, 5)
ax = fig.add_subplot(1, 1, 1)
# ax.set_yscale("log")で片対数グラフ (y軸が対数スケール) となる
ax.set_yscale("log")
ax.plot(x, 5 * np.exp(- 2 * x), marker = "o")
ax.set_title("片対数グラフでは指数関数が直線となる")
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$5e^{-2x}$")
plt.show()
両対数グラフ
fig = plt.figure()
x = np.linspace(1, 100, 10)
ax = fig.add_subplot(1, 1, 1)
# ax.set_xscale("log")を追加して両対数グラフ (x軸、y軸が対数スケール) となる
ax.set_xscale("log")
ax.set_yscale("log")
ax.plot(x, 10 * x ** (- 5 / 3), marker = "o")
ax.set_title("両対数グラフではべき関数が直線となる")
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$10x^{-5/3}$")
plt.show()
対数グラフでticks (軸の数値の設定) を使うときはticklabelsと併用すると良い (というか併用しないと上手く表示されないことがある)
# 対数スケールのグラフでは基本的に小目盛りが表示されたままとなる
# 無理やり消したい場合は次の記述を加えると良い
plt.rcParams["ytick.minor.size"] = 0 # x軸が対数スケールの場合にはxtick.minorとする
fig = plt.figure()
x = np.linspace(0, 5, 5)
ax = fig.add_subplot(1, 1, 1)
ax.set_yscale("log")
# y軸に設定したい数値のベクトルを設定しておく
vector_y = np.array([0.02, 0.7, 1.4, 5])
ax.set_yticks(vector_y)
ax.set_yticklabels(vector_y)
ax.plot(x, 5 * np.exp(- 2 * x), marker = "o")
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$5e^{-2x}$")
plt.show()
基本的なヒストグラム
fig = plt.figure()
x = np.hstack([np.random.normal(0, 1, 1000), np.random.normal(5, 2, 1000)])
ax = fig.add_subplot(1, 1, 1)
# ax.hist(ベクトル)でヒストグラムとなる
ax.hist(x)
ax.set_xlabel(r"$x$")
ax.set_ylabel("頻度")
plt.show()
階級数を変える
fig = plt.figure()
x = np.hstack([np.random.normal(0, 1, 1000), np.random.normal(5, 2, 1000)])
ax = fig.add_subplot(1, 1, 1)
# binsオプションで階級数を指定できる
ax.hist(x, bins = 20)
ax.set_xlabel(r"$x$")
ax.set_ylabel("頻度")
plt.show()
頻度ではなく確率分布にする
fig = plt.figure()
x = np.hstack([np.random.normal(0, 1, 1000), np.random.normal(5, 2, 1000)])
ax = fig.add_subplot(1, 1, 1)
# density = Trueで頻度ではなく確率分布となる
ax.hist(x, bins = 20, density = True)
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$p(x)$")
plt.show()
棒を外枠のみにする (複数のヒストグラムを表示するのに便利)
fig = plt.figure()
x1 = np.random.normal(0, 1, 1000)
x2 = np.random.normal(5, 2, 1000)
x3 = np.hstack([x1, x2])
ax = fig.add_subplot(1, 1, 1)
# histtype = "step"で外枠のみとなる
ax.hist(x1, bins = 20, density = True, histtype = "step", label = r"$p_1(x)$")
ax.hist(x2, bins = 20, density = True, histtype = "step", label = r"$p_2(x)$")
ax.hist(x3, bins = 20, density = True, histtype = "step", label = r"$p_{1 + 2}(x)$")
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$p(x)$")
ax.legend()
plt.show()
ヒストグラムに関する注意点
折れ線グラフのヒストグラムなど、より高度なものをプロットしたい場合はヒストグラムのベクトルを得なければならない。StatsBaseのfit関数によって得ることができるが、結構面倒くさい (このあたりはPython (numpy) の圧倒的勝ち)。scatterによる散布図で点の色に対して、別のベクトルを指定する
fig = plt.figure()
height = np.array([172.3, 165, 179.6, 174.5, 173.8, 165.4, 164.5, 174.9, 166.8, 185])
mass = np.array([75.24, 55.8, 78, 71.1, 67.7, 55.4, 63.7, 77.2, 67.5, 84.6])
fat = np.array([21.3, 15.7, 20.1, 18.4, 17.1, 22, 32.2, 36.9, 27.6, 14.4])
ax = fig.add_subplot(1, 1, 1)
# cオプションでベクトルを指定することにより、そのベクトルの値に対応した点の色になる
ax.scatter(height, mass, c = fat)
ax.set_xlabel("身長 [cm]")
ax.set_ylabel("体重 [kg]")
plt.show()
色と数値を対応させるカラーバーを表示
fig = plt.figure()
height = np.array([172.3, 165, 179.6, 174.5, 173.8, 165.4, 164.5, 174.9, 166.8, 185])
mass = np.array([75.24, 55.8, 78, 71.1, 67.7, 55.4, 63.7, 77.2, 67.5, 84.6])
fat = np.array([21.3, 15.7, 20.1, 18.4, 17.1, 22, 32.2, 36.9, 27.6, 14.4])
ax = fig.add_subplot(1, 1, 1)
# 散布図scatter自体を変数として代入 (今の場合はc_pointsという変数)
c_points = ax.scatter(height, mass, c = fat)
# fig.colorbar(c_points)でカラーバーが追加される
fig.colorbar(c_points)
ax.set_xlabel("身長 [cm]")
ax.set_ylabel("体重 [kg]")
plt.show()
色、カラーバーに関するオプション1
fig = plt.figure()
height = np.array([172.3, 165, 179.6, 174.5, 173.8, 165.4, 164.5, 174.9, 166.8, 185])
mass = np.array([75.24, 55.8, 78, 71.1, 67.7, 55.4, 63.7, 77.2, 67.5, 84.6])
fat = np.array([21.3, 15.7, 20.1, 18.4, 17.1, 22, 32.2, 36.9, 27.6, 14.4])
ax = fig.add_subplot(1, 1, 1)
# vmaxオプションとvminオプションで色に対する最大値と最小値を設定できる
c_points = ax.scatter(height, mass, c = fat, vmin = 10, vmax = 40)
# labelオプションでカラーバーに名前が付く
fig.colorbar(c_points, label = "体脂肪率 [%]")
ax.set_xlabel("身長 [cm]")
ax.set_ylabel("体重 [kg]")
plt.show()
色、カラーバーに関するオプション2
fig = plt.figure()
height = np.array([172.3, 165, 179.6, 174.5, 173.8, 165.4, 164.5, 174.9, 166.8, 185])
mass = np.array([75.24, 55.8, 78, 71.1, 67.7, 55.4, 63.7, 77.2, 67.5, 84.6])
fat = np.array([21.3, 15.7, 20.1, 18.4, 17.1, 22, 32.2, 36.9, 27.6, 14.4])
ax = fig.add_subplot(1, 1, 1)
# cmapオプションで色使いが変えられる
# viridis : デフォルトの青→黄色
# jet : 虹色
# hsv : 周期的な虹色
c_points = ax.scatter(height, mass, c = fat, cmap = "hsv")
# ticksオプションで設定した値が表示される
# さらにカラーバー自体を別の変数に代入し (今の場合はcbar) 、cbar.ax.set_yticklabelsで、表示を変えられる
cbar = fig.colorbar(c_points, label = "体脂肪率 [%]", ticks = np.array([15, 25, 35]))
cbar.ax.set_yticklabels(np.array(["低", "中", "高"]))
ax.set_xlabel("身長 [cm]")
ax.set_ylabel("体重 [kg]")
plt.show()
点のサイズ
fig = plt.figure()
height = np.array([172.3, 165, 179.6, 174.5, 173.8, 165.4, 164.5, 174.9, 166.8, 185])
mass = np.array([75.24, 55.8, 78, 71.1, 67.7, 55.4, 63.7, 77.2, 67.5, 84.6])
fat = np.array([21.3, 15.7, 20.1, 18.4, 17.1, 22, 32.2, 36.9, 27.6, 14.4])
age = np.array([27, 25, 31, 32, 28, 36, 42, 33, 54, 28])
ax = fig.add_subplot(1, 1, 1)
# sオプションで点のサイズを決められる
# (plotの場合はmarkersize)
# ただしscatterの場合はcにベクトルを指定することによって点ごとのサイズを変えられる
c_points = ax.scatter(height, mass, c = fat, s = age * 4)
cbar = fig.colorbar(c_points, label = "体脂肪率 [%]", ticks = np.array([15, 25, 35]))
cbar.ax.set_yticklabels(np.array(["低", "中", "高"]))
ax.set_xlabel("身長 [cm]")
ax.set_ylabel("体重 [kg]")
ax.set_title("マーカーサイズは年齢に対応")
plt.show()
imshowは行列を見たまま表示するようなイメージ
fig = plt.figure()
matrix = np.array([[2, 3, 0, 0],
[1, 2, 3, 0],
[0, 1, 2, 3]])
ax = fig.add_subplot(1, 1, 1)
# vmin, vmax, cmapオプションも使える (scatterのところを参照)
c_matrix = ax.imshow(matrix)
# カラーバーも使える
# label, ticksオプションも使える
fig.colorbar(c_matrix, label = "行列の値")
ax.set_xlabel("列")
ax.set_ylabel("行")
plt.show()
カラーバーの高さが気持ち悪い場合
fig = plt.figure()
matrix = np.array([[2, 3, 0, 0],
[1, 2, 3, 0],
[0, 1, 2, 3]])
ax = fig.add_subplot(1,1,1)
c_matrix = ax.imshow(matrix)
# 手っ取り早くはfraction = (行の大きさ) / (列の大きさ) * 0.046, pad = 0.04で揃えられる
fig.colorbar(c_matrix, label = "行列の値", fraction = 3 / 4 * 0.046, pad = 0.04)
ax.set_xlabel("列")
ax.set_ylabel("行")
plt.show()
pcolorは等高線のようなイメージで、x座標とy座標を指定できる
ただし何も指定しないと、行列の行方向がxに、列がy方向になる (imshowと逆)
fig = plt.figure()
# xとyの値に対するベクトルを作成する
x = np.linspace(-2*np.pi, 2*np.pi, 100)
y = np.linspace(-np.pi, np.pi, 100)
# xとyを行列にする
x, y = np.meshgrid(x, y)
ax = fig.add_subplot(1, 1, 1)
# 基本はax.pcolor(x座標を指定する行列, y座標を指定する行列, ヒートマップに対する行列, shading = "auto")
# vmin, vmax, cmapオプションも使える (scatterのところを参照)
c_pcolor = ax.pcolor(x, y, np.sin(x + y), shading = "auto")
# カラーバーも使える
# label, ticksオプションも使える
fig.colorbar(c_pcolor, label = r"$\sin(x+y)$")
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$y$")
ax.set_xticks(np.array([-2*np.pi, -np.pi, 0, np.pi, 2*np.pi]))
ax.set_xticklabels(np.array([r"$-2\pi$", r"$-\pi$", r"$0$", r"$\pi$", r"$2\pi$"]))
ax.set_yticks(np.array([-np.pi, 0, np.pi]))
ax.set_yticklabels(np.array([r"$-\pi$", r"$0$", r"$\pi$"]))
plt.show()
3次元グラフの基本
# 3次元グラフは基本的にマウスを使って視点を自由に変えられると便利である
# それを可能にするために別ウインドウでグラフを描画する必要がある
# %matplotlib tk (あるいはqt) とすれば別ウインドウでグラフが開く
# 逆に%matplotlib inlineとすればJupyter notebook上にグラフが表示される
%matplotlib tk
fig = plt.figure()
t = np.linspace(0, 2*np.pi, 100)
x = np.sin(t)
y = np.cos(t)
z = t + np.sin(2 * t)
# projection = "3d"を追加することで3次元グラフとなる
ax = fig.add_subplot(1, 1, 1, projection = "3d")
# plotは3次元における折れ線グラフで、z座標のベクトルも必要になる
ax.plot(x, y, z)
# ax.set_zlabel, ax.set_zticks, ax.set_zticklabels, ax.set_zlimも使える
ax.set_xlabel(r"$x = \sin(t)$")
ax.set_ylabel(r"$y = \cos(t)$")
ax.set_zlabel(r"$z = t + \sin(2t)$")
plt.show()
散布図
%matplotlib tk
fig = plt.figure()
age = np.array([27, 25, 31, 32, 28, 36, 42, 33, 54, 28])
height = np.array([172.3, 165, 179.6, 174.5, 173.8, 165.4, 164.5, 174.9, 166.8, 185])
mass = np.array([75.24, 55.8, 78, 71.1, 67.7, 55.4, 63.7, 77.2, 67.5, 84.6])
fat = np.array([21.3, 15.7, 20.1, 18.4, 17.1, 22, 32.2, 36.9, 27.6, 14.4])
ax = fig.add_subplot(1, 1, 1, projection = "3d")
# 3次元scatterは2次元と同様に色に対応するベクトルを指定できる
c_points = ax.scatter(height, mass, fat, c = age)
# カラーバーがデフォルトだとグラフに近いため、padオプションで少し離しておくと良い
plt.colorbar(c_points, label = "年齢 [歳]", pad = 0.15)
ax.set_xlabel("身長 [cm]")
ax.set_ylabel("体重 [kg]")
ax.set_zlabel("体脂肪率 [%]")
plt.show()
曲面 (ワイヤーフレーム) : pcolorに代わる表示方法
%matplotlib tk
fig = plt.figure()
x = np.linspace(- 2*np.pi, 2*np.pi,100)
y = np.linspace(- np.pi, np.pi, 100)
x, y = np.meshgrid(x, y)
ax = fig.add_subplot(1, 1, 1, projection = "3d")
# ax.plot_wireframeで曲面表示
ax.plot_wireframe(x, y, np.sin(x) + np.cos(y))
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$y$")
ax.set_zlabel(r"$\sin(x)+\cos(y)$")
ax.set_xticks(np.array([-2*np.pi, -np.pi, 0, np.pi, 2*np.pi]))
ax.set_xticklabels(np.array([r"$-2\pi$", r"$-\pi$", r"$0$", r"$\pi$", r"$2\pi$"]))
ax.set_yticks(np.array([-np.pi, 0, np.pi]))
ax.set_yticklabels(np.array([r"$-\pi$", r"$0$", r"$\pi$"]))
plt.show()
色付き曲面
%matplotlib tk
fig = plt.figure()
x = np.linspace(- 2*np.pi, 2*np.pi,100)
y = np.linspace(- np.pi, np.pi, 100)
x, y = np.meshgrid(x, y)
ax = fig.add_subplot(1, 1, 1, projection = "3d")
# cmapオプション付きのax.plot_surfaceで色付き曲面表示
c_surface = ax.plot_surface(x, y, np.sin(x) + np.cos(y), cmap = "viridis")
plt.colorbar(c_surface, pad = 0.15)
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$y$")
ax.set_zlabel(r"$\sin(x)+\cos(y)$")
ax.set_xticks(np.array([-2*np.pi, -np.pi, 0, np.pi, 2*np.pi]))
ax.set_xticklabels(np.array([r"$-2\pi$", r"$-\pi$", r"$0$", r"$\pi$", r"$2\pi$"]))
ax.set_yticks(np.array([-np.pi, 0, np.pi]))
ax.set_yticklabels(np.array([r"$-\pi$", r"$0$", r"$\pi$"]))
plt.show()
アニメーションはいわゆるパラパラマンガの要領で作成する
つまり、ある (短い) 時間だけグラフを表示する、という動作を繰り返す
PyPlotの場合グラフ消去→グラフ表示を繰り返すことになる
# アニメーションも3次元グラフと同様に別ウインドウで表示する
# ちなみにmatplotlib.pyplot単体でアニメーションの保存は面倒なので諦めたほうが良い
%matplotlib tk
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
q = np.pi / 4
v0 = 5.0
v0x = v0 * np.cos(q)
v0y = v0 * np.sin(q)
g = 9.8
t = np.array([0.0])
x = np.array([0.0])
y = np.array([0.0])
# アニメーションを表示するためのfor文
for it in range(200):
t_now = it * 0.0035
x_now = v0x * t_now
y_now = v0y * t_now - 0.5 * g * t_now ** 2
t = np.append(t, t_now)
x = np.append(x, x_now)
y = np.append(y, y_now)
# グラフの描画
# 前のグラフを一旦消去
ax.cla()
# 新しいグラフのプロット
ax.scatter(x_now, y_now)
ax.plot(x, y)
ax.set_xlabel("水平距離 [m]")
ax.set_ylabel("垂直距離 [m]")
# 軸の最大、最小は決めておいたほうが良い
ax.set_xlim(0, 3)
ax.set_ylim(0, 0.8)
ax.set_title("t = " + "{:5.3f}".format(t_now) + " [秒]")
# グラフを描画し、() の中の時間 (秒) だけ待つ
plt.pause(0.05)