📈
ライブラリ「Matplotlib」基礎(可視化)
[!Important]+ Goals
データ可視化コースでは、Matplotlibを使ってデータを可視化する方法を学びます。折れ線グラフ、円グラフ、ヒストグラムなどの作成から3Dグラフの作成方法まで学びます。
[!abstract]+ Curriculum
1.データ可視化のための準備
- 様々なグラフ
- 乱数生成
- 時系列データ
- データの操作
- Matplotlibの使い方
- 一種類のデータを可視化しよう
- 複数のデータを可視化しよう 1
- 複数のデータを可視化しよう 2
- いろいろなグラフを作ろう
- 折れ線グラフ
- 棒グラフ
- ヒストグラム
- 散布図
- 円グラフ
- 3Dグラフ
- 添削問題
データ可視化のための準備
乱数生成
- シード設定
#np/random/seed
import numpy as np
# シードを設定せずに、X, Y にそれぞれ5つの乱数を格納し表示する
print("シードを設定しない場合")
X = np.random.randn(5)
print("X:", X)
Y = np.random.randn(5)
print("Y:", Y)
print()
# シードを設定して、x, y にそれぞれ5つの乱数を格納し表示する
print("シードを設定した場合")
np.random.seed(0) # シードを設定
x = np.random.randn(5)
print("x:", x)
np.random.seed(1) # シードを設定
y = np.random.randn(5)
print("y:", y)
# 何も書き込まずに実行してください
- 正規分布に従う乱数を生成する
#np/random/normal
import numpy as np
import matplotlib.pyplot as plt
# シードの値を0に設定してください
np.random.seed(0)
# 正規分布に従う乱数を10,000個生成し、変数x に代入してください
x = np.random.randn(10000)
# 可視化
plt.hist(x, bins='auto')
plt.show()
- 二項分布に従う乱数を生成する
#np/random/binomial
import numpy as np
# シードを設定
np.random.seed(0)
# 0.5の確率で成功する試行を100回行なったときの成功数を10,000回分求めて変数nums に代入してください
nums = np.random.binomial(100, 0.5, 10000)
# 成功率の平均を出力します
print(nums.mean()/100)
- リストからランダムに選択
#np/random/choice
import numpy as np
x = ['Apple', 'Orange', 'Banana', 'Pineapple', 'Kiwifruit', 'Strawberry']
# シードを設定
np.random.seed(0)
# リストx の中からランダムに5個選んで変数y に代入してください
y = np.random.choice(x,5)
print(y)
時系列データ
- データタイム 타입
#dt/datetime
import datetime as dt
# 1992年10月22日を表すdatetimeオブジェクトを作成して、変数x に代入してください
x = dt.datetime(1992,10,22)
# 出力
print(x)
- タイメデルタ 타입
#dt/timedelta
import datetime as dt
# 1時間半を表すtimedeltaオブジェクトを作成して、変数x に代入してください
x = dt.timedelta(hours = 1.5)
# 出力
print(x)
- datetime タイプと timedelta タイプの演算
import datetime as dt
# 1992年10月22日を表すdatetimeオブジェクトを生成して、変数x に代入してください
x = dt.datetime(1992,10,22)
# 変数x から1日後を表すdatetimeオブジェクトを変数y に代入してください
y = x + dt.timedelta(days=1)
# 出力
print(y)
- 時間を表す文字列から datetime オブジェクトを作成します。
#dt/datetime/str
import datetime as dt
# 1992年10月22日を表す文字列を"年-月-日"の形式で変数s に代入してください
s = "1992-10-22"
# 変数s を1992年10月22日を表すdatetimeオブジェクトに変換して、変数x に代入してください
x = dt.datetime.strptime(s, "%Y-%m-%d")
# 出力
print(x)
データ操作
- 変換 : 文字列タイプ → 数値タイプ
# 変数x, y に文字列を代入
x = '64'
y = '16'
# 変数x, y を int() を用いて数値型に変換し、数値的な和を変数z に代入してください
z = int(x) + int(y)
# 変数x, yを文字列のまま足したものを変数cに代入してください。
c = x+y
# 変数の値を出力
print(z)
print(c)
- 等間隔数列生成 1 : 間隔指定
#np/arange
import numpy as np
# 変数x に0から10までの偶数列を代入してください
x = np.arange(0, 11, 2)
# 出力
print(x)
- 等間隔列生成2:個数指定。指定がなければ50個がデフォルト。
#np/linspace
import numpy as np
# 0から10までの範囲を等間隔に分ける5点を変数x に代入してください
x = np.linspace(0,10,5)
# 出力
print(x)
Matplotlib の使い方
#matplotlib(マットプロットリブ
一種類のデータを可視化しよう
#plt #plt/lim #plt/title #plt/label #plt/grid #plt/ticks
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2*np.pi)
y = np.sin(x)
# グラフのタイトルを設定する
plt.title("y=sin(x)")
# グラフのx軸とy軸にラベルを設定する
plt.xlabel("x-axis")
plt.ylabel("y-axis")
# グラフにグリッドを表示する
plt.grid(True)
plt.ylim([-1.5, 1.5])
# positionsとlabelsの設定
positions = [0, np.pi/2, np.pi, np.pi*3/2, np.pi*2]
labels = ["0°", "90°", "180°", "270°", "360°"]
# グラフのx軸に目盛りを設定してください
plt.xticks(positions, labels)
# データx, yをグラフにプロットし、表示する
plt.plot(x, y)
plt.show()
様々な種類のデータを可視化しよう 1
#plt/レジェンド #plt/カラー
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2*np.pi)
y1 = np.sin(x)
y2 = np.cos(x)
# グラフのタイトルを設定する
plt.title("graphs of trigonometric functions")
# グラフのx軸とy軸にラベルを設定する
plt.xlabel("x-axis")
plt.ylabel("y-axis")
# グラフにグリッドを表示する
plt.grid(True)
# positionsとlabelsの設定
positions = [np.pi/2, np.pi, np.pi*3/2, np.pi*2]
labels = ["90°", "180°", "270°", "360°"]
# グラフのx軸に目盛りを設定する
plt.xticks(positions, labels)
# データx, y1 をグラフにプロットし、"y=sin(x)"と系列ラベルを設定して赤で表示してください
plt.plot(x,y1,label="y=sin(x)", color='r')
# データx, y2 をグラフにプロットし、"y=cos(x)"と系列ラベルを設定して青で表示してください
plt.plot(x,y2,label="y=cos(x)", color='b')
# 系列ラベルを表示してください
plt.legend()
plt.show()
様々な種類のデータを可視化しよう 2
#plt/figsize #plt/subplot #plt/adjust #plt/subplot/lim #plt/subplot/title #plt/subplot/label #plt/subplot/grid #plt/subplot/ticks
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2*np.pi)
y = np.sin(x)
positions = [0, np.pi/2, np.pi, np.pi*3/2, np.pi*2]
labels = ["0°", "90°", "180°", "270°", "360°"]
# figureオブジェクトを作成
fig = plt.figure(figsize=(9, 6))
# figureを2×3に分割
# 5番目にはデータx, yをプロットし、他は空白のままにしておく
ax1 = fig.add_subplot(2, 3, 1)
ax2 = fig.add_subplot(2, 3, 2)
ax3 = fig.add_subplot(2, 3, 3)
ax4 = fig.add_subplot(2, 3, 4)
ax5 = fig.add_subplot(2, 3, 5)
ax5.plot(x, y)
ax6 = fig.add_subplot(2, 3, 6)
# サブプロットax5のグラフにグリッドを表示してください
ax5.grid(True)
# figure内のaxesを、縦横ともに1の間隔を空けてください。
fig.subplots_adjust(wspace = 1, hspace=1)
# サブプロットax5のy軸の表示範囲を 0〜1 に設定してください。
ax5.set_ylim([0,1])
# サブプロットax5のグラフのタイトルを "y=sin(x)" に設定してください
ax5.set_title("y=sin(x)")
# サブプロットax5のx軸のラベルを "x-axis"、y軸のラベルを "y-axis" に設定してください
ax5.set_xlabel("x-axis")
ax5.set_ylabel("y-axis")
# サブプロットax5のグラフのx軸に目盛りを設定してください
ax5.set_xticks(positions)
# サブプロットax5のグラフのx軸に目盛りのラベルを設定してください
ax5.set_xticklabels(labels)
plt.show()
いろいろなグラフを作ろう
折れ線グラフ
import numpy as np
import matplotlib.pyplot as plt
days = np.arange(1, 11)
weight = np.array([10, 14, 18, 20, 18, 16, 17, 18, 20, 17])
# 表示の設定
plt.ylim([0, weight.max()+1])
plt.xlabel("days")
plt.ylabel("weight")
# 円マーカーを赤色でプロットし、青の破線の折れ線グラフを作成してください
plt.plot(days, weight, linestyle="--", color="b", marker="o", markerfacecolor="r")
plt.show()
バーグラフ
#plt/バー #plt/バー/tick_label #plt/バー/stacked
import numpy as np
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5, 6]
y1 = [12, 41, 32, 36, 21, 17]
y2 = [43, 1, 6, 17, 17, 9]
labels = ["Apple", "Orange", "Banana", "Pineapple", "Kiwifruit", "Strawberry"]
# 積み上げ棒グラフを作成し、横軸にラベルを設定してください
plt.bar(x,y1 , tick_label=labels)
# bottomで値を指定することでその分の余白が出来る
plt.bar(x, y2, bottom=y1)
# 系列ラベルの設定が可能
plt.legend(("y1", "y2"))
plt.show()
ヒストグラム
#plt/hist #plt/hist/bins #plt/hist #plt/hist/normalize #plt/hist/cumulative
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
data = np.random.randn(10000)
# 正規化されたビン数100の累積ヒストグラムを作成してください
plt.hist(data, bins=100, density=True, cumulative=True)
plt.show()
散布図
#plt/scatter #plt/scatter/marker #plt/scatter/marker_size
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
x = np.random.choice(np.arange(100), 100)
y = np.random.choice(np.arange(100), 100)
z = np.random.choice(np.arange(100), 100)
# マーカーの種類を四角、色を赤に設定して散布図を作成してください
plt.scatter(x,y,marker="s",color='r', s = z)
plt.show()
#plt/スキャッター/グラデーション #plt/カラーバー
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
x = np.random.choice(np.arange(100), 100)
y = np.random.choice(np.arange(100), 100)
z = np.random.choice(np.arange(100), 100)
# 変数zに応じた値で、マーカーの色を青系統のグラデーションで表示してください
plt.scatter(x, y, c=z, cmap="Blues")
# カラーバーを表示してください
plt.colorbar()
plt.show()
円グラフ
#plt/パイ #plt/軸 #plt/パイ/ラベル #plt/パイ/エクスプロード
import matplotlib.pyplot as plt
data = [60, 20, 10, 5, 3, 2]
labels = ["Apple", "Orange", "Banana", "Pineapple", "Kiwifruit", "Strawberry"]
explode = [0, 0, 0.1, 0, 0, 0]
# 変数dataに変数labelsのラベルを指定し、Bananaを目立たせた円グラフを描画してください
plt.pie(data, labels = labels, explode = explode)
plt.axis("equal")
plt.show()
3Dグラフ
#plt/3d #plt/3d/surface #plt/3d/gradation
- 3Dグラフを描くには、3D機能を持つサブプロットを作成する必要があります。
-
projection="3d"
を指定します。
-
import numpy as np
import matplotlib.pyplot as plt
# 3D描画を行うために必要なライブラリ
from mpl_toolkits.mplot3d import Axes3D
# カラーマップを表示するためのライブラリ
from matplotlib import cm
t = np.linspace(-2*np.pi, 2*np.pi)
X, Y = np.meshgrid(t, t)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
# Figureオブジェクトを作成
fig = plt.figure(figsize=(6, 6))
# サブプロットaxを追加
ax = fig.add_subplot(111, projection="3d")
# サブプロットaxにzの値にカラーマップを適用してください
ax.plot_surface(X,Y,Z,cmap=cm.coolwarm)
plt.show()
#plt/3d/バー
import matplotlib.pyplot as plt
import numpy as np
# 3D描画を行うために必要なライブラリ
from mpl_toolkits.mplot3d import Axes3D
# Figureオブジェクトを作成
fig = plt.figure(figsize=(5, 5))
# サブプロットaxを追加
ax = fig.add_subplot(1,1,1, projection="3d")
# x, y, zの位置を決める
xpos = [i for i in range(10)]
ypos = [i for i in range(10)]
zpos = np.zeros(10)
# x, y, zの変化量を決める
dx = np.ones(10)
dy = np.ones(10)
dz = [i for i in range(10)]
# 3次元のbarを作成してください
ax.bar3d(xpos,ypos,zpos,dx,dy,dz)
plt.show()
#plt/3d/スキャッター
import numpy as np
import matplotlib.pyplot as plt
# 3D描画を行うために必要なライブラリ
from mpl_toolkits.mplot3d import Axes3D
np.random.seed(0)
x = np.random.randn(1000)
y = np.random.randn(1000)
z = np.random.randn(1000)
# Figureオブジェクトを作成
fig = plt.figure(figsize=(6, 6))
# サブプロットaxを追加
ax = fig.add_subplot(1,1,1, projection="3d")
# 3D散布図を作成してください
ax.scatter3D(x,y,z)
plt.show()
添削問題
基本 : 2x2 サブプロット
- マルチプロット、線の色とスタイルの指定
import math
import matplotlib.pyplot as plt
import numpy as np
# 描画用の点を用意しています
x1 = np.linspace(-1, 1, 200)
y1 = [x**4 - x**2 + 6 for x in x1]
x2 = np.linspace(-8, -1, 700)
y2 = [12 / (abs(x) + 1) for x in x2]
x3 = np.linspace(1, 8, 700)
y3 = [12 / (abs(x) + 1) for x in x3]
x4 = np.linspace(-2, 2, 400)
y4 = [1/2 * math.cos(6*x) + 7/2 for x in x4]
# figureオブジェクトを作成してください
fig = plt.figure()
# axesオブジェクトを2行2列に分割し、左上に (x1,y1) を描画してください
ax1 = fig.add_subplot(2,2,1)
ax1.plot(x1,y1)
# axesオブジェクトを2行2列に分割し、右上に (x2,y2), (x3,y3) を重ねて描画してください
# なお、グラフの色は全て赤色にしてください
ax2 = fig.add_subplot(2,2,2)
ax2.plot(x2,y2, 'r',
x3,y3,'r')
# axesオブジェクトを2行2列に分割し、左下に (x4,y4) を描画してください
# なお、グラフのスタイルは破線にしてください
ax3 = fig.add_subplot(2,2,3)
ax3.plot(x4,y4, linestyle="--")
# axesオブジェクトを2行2列に分割し、右下に (x1,y1), (x2,y2), (x3,y3), (x4,y4) を重ねて描画してください
# なお、グラフの色は全て青色にしてください
ax4 = fig.add_subplot(2,2,4)
ax4.plot(x1,y1,'b',
x2,y2,'b',
x3,y3,'b',
x4,y4,'b')
plt.show()
応用 : モンテカルロ法
import matplotlib.pyplot as plt
import numpy as np
import math
import time
np.random.seed(100)
X = 0 # 的に当たった回数です
# 試行回数Nを指定してください。
N = 100000
# 四分円の境界の方程式[y=√1-x^2 (0<=x<=1)]を描画しています。
circle_x = np.arange(0, 1, 0.001)
circle_y = np.sqrt(1 - circle_x * circle_x)
plt.figure(figsize=(5, 5))
plt.plot(circle_x, circle_y)
# N回の試行にかかる時間を計測します。
start_time = time.perf_counter()
#プロット用の空の配列を用意
internal_x = []
internal_y = []
external_x = []
external_y = []
# N回の試行を行っています。
for i in range(N):
# 0から1の間で一様乱数を発生させ、変数score_xに格納してください。
score_x = np.random.rand()
# 0から1の間で一様乱数を発生させ、変数score_yに格納してください。
score_y = np.random.rand()
if score_x * score_x + score_y * score_y <= 1:
# 的に入ったものはinternal_x, internal_yに追加してください。
internal_x.append(score_x)
internal_y.append(score_y)
# 得点Xを1追加してください
X += 1
else:
# 的から外れたものはexternal_x, external_yに追加してください。
external_x.append(score_x)
external_y.append(score_y)
# piの近似値をここで計算してください。
# 小数のpiを求めるため、明示的にXとNをfloat()に入れてください。
pi = 4 * float(X) / float(N)
# モンテカルロ法の実行時間を計算しています。
end_time = time.perf_counter()
time = end_time - start_time
# 円周率の結果を表示
print("円周率:%.6f" % pi)
print("実行時間:%f" % (time))
# 散布図を描画してください。四分円内にある点は赤で、四分円外にある点は青で描画してください。
plt.scatter(internal_x, internal_y, c = 'r')
plt.scatter(external_x, external_y, c = 'b')
# 結果を表示
plt.grid(True)
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
Discussion