Contents
グラフで日本語を使うには
ふつうに日本語を使うとエラーになるので、以下のように書く。
1 2 |
import matplotlib.pyplot as plt plt.rcParams["font.family"] = 'Yu Mincho' |
グラフのデフォルトのスタイルを変更する
1 |
plt.style.use('ggplot') |
とすればいい感じのスタイルになる。
1 |
print(plt.style.available) |
とすると利用可能なスタイルの一覧を取得できる。
add_subplotの引数を統一しないとどうなるのか
plt.figureは全体の描画領域を生成する。その領域のどの部分に描くかを指定するのがadd_subplot。
以下のようにするとふつうに描画される。生成した描画領域全体をもれなく使うので無駄がない。
1 2 3 4 5 6 |
fig = plt.figure(figsize=(16,9)) ax1 = fig.add_subplot(1, 2, 1) ax2 = fig.add_subplot(1, 2, 2) ax1.plot([1,2], [1,2]) ax2.plot([1,2],[2,1]) plt.show() |
素朴な疑問としてadd_subplotの第一引数と第二引数を、1回目と2回目で変えたらどうなるのか。
1 2 3 4 5 6 |
fig = plt.figure(figsize=(16,9)) ax1 = fig.add_subplot(1, 2, 1) ax2 = fig.add_subplot(1, 100, 2) ax1.plot([1,2], [1,2]) ax2.plot([1,2],[2,1]) plt.show() |
この場合、2個目のグラフは全体を100分割して左から2番目の細長い領域に描画される。1個目と2個目のグラフは重なっている。
ax1とax2はお互いの存在を知らないので、分割方法のつじつまが合わないと重なることがある。
うっかりつじつまが合わなくなる可能性をなくすには、plt.subplotsを使うといいと思う。
複数のグラフを描く際
複数のグラフを描く際、axes[i, j].imshow()みたいな感じで添え字を使って描くより、↓みたいにaxes.ravel()でまわしたほうがすっきり書ける。
1 2 3 4 5 |
fig, axes = plt.subplots(3, 10, figsize=(15, 5)) fig.subplots_adjust(wspace=0.5, hspace=0.5) for ax, image, label in zip(axes.ravel(), images, labels): ax.imshow(image) ax.set_title(label) |
ラベルごとにマークを変えて散布図を描く
にはmglearn.discrete_scatterを使う。
1 2 3 4 5 6 7 8 9 |
from sklearn import datasets import matplotlib.pyplot as plt import mglearn N = 300 X, y = datasets.make_moons(N, noise=0.3) mglearn.discrete_scatter(X[:,0], X[:,1], y) plt.show() |
あとで知ったが、plt.scatterでも可能。
1 2 |
plt.scatter(X[:,0], X[:,1], c=y) plt.show() |
X_trainのどれかひとつの列(特徴)をとりあえずプロットしたいとき。
1 2 3 |
col = 0 x = np.linspace(-2, 2, len(X_train[:, col])) plt.plot(x, X_train[:, col]) |
X_trainの要素数とおなじ個数の横軸データをlinspaceで生成してプロット。
横軸→縦軸をつくるときはnp.arangeでもいいが、縦軸→横軸をつくるときはnp.linspaceを使う。横軸と縦軸の要素数は等しくなければならない。
決定境界を描画する
np.mgridで格子状の点の配列を生成し、各点での確率(あるいは予測ラベル)を高さとしてplt.contourfで等高線を描画する。
注意点として、np.mgridは関数ではなくオブジェクトなので大括弧で引数を指定する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn import datasets from sklearn.model_selection import train_test_split import mglearn plt.rcParams['font.family'] = 'Yu Mincho' plt.style.use('ggplot') X, y = datasets.make_moons(n_samples=1000, noise=0.2) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) # モデルの学習 from sklearn.svm import SVC model = SVC(probability=True).fit(X_train, y_train) pred = model.predict(X_test) (pred == y_test).sum() / len(y_test) # モデルの性能を評価 # 決定境界を描画 x0, x1 = np.mgrid[X[:, 0].min():X[:, 0].max():0.01, X[:, 1].min():X[:, 1].max():0.01] # 0.01は刻み幅 grid_points = np.c_[x0.ravel(), x1.ravel()] # モデルで予測するために結合 z = model.predict_proba(grid_points) mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train) # plt.contourf(x0, x1, z.reshape(X0.shape)) # 確率ではない場合(model.predict(grid_points)の場合) plt.contourf(x0, x1, z[:, 0].reshape(x0.shape)) plt.show() |
np.mgridではなくnp.meshgridでも描ける。スライスが使えないのでやや冗長となるのでnp.mgridのほうがいいかな。
1 2 3 4 5 6 7 8 9 10 |
n_samples = 100 X0_ = np.linspace(X[:, 0].min(), X[:, 0].max(), n_samples) X1_ = np.linspace(X[:, 1].min(), X[:, 1].max(), n_samples) X0, X1 = np.meshgrid(X0_, X1_) grid_points = np.c_[X0.ravel(), X1.ravel()] # モデルで予測するために結合 z= model.predict_proba(grid_points) mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train) # plt.contourf(X0_, X1_, z.reshape(X0.shape)) # 確率ではない場合(model.predict(grid_points)の場合) plt.contourf(X0_, X1_, z[:, 0].reshape(X0.shape)) plt.show() |
グラフの色使いがみにくい場合
黄色とかで点を示されるとみにくい。そんなときはcmap属性でカラーマップを指定する。こんな感じ↓
1 2 3 4 5 6 |
plt.scatter( df['petal length (cm)'], df['sepal width (cm)'], c=df['target'], cmap=plt.cm.Accent ) |
とはいえcmapを使うとdf[‘target’]の数値が小さい点は白く表示されてもっと見えにくくなったりする。。。もしdf[‘target’]の数値の種類が少ない場合は数値と色の対応を辞書で用意すればしのげる。
1 2 3 4 5 |
plt.scatter( [1,2,3,4], [1,2,3,4], c=list(map(lambda x: {0: 'red', 1: 'blue', 2: 'yellow'}[x], [0,1,0,2])) ) |
df[‘target’]の数値の種類が多い場合はどうすればいいんかな。いまのところわからん。
点が黄色や白で見にくい場合、edgecolors属性を指定して線に色をつけてやればいい。
1 2 3 |
plt.scatter(X, y, c=y, cmap=plt.cm.Blues, edgecolors='blue') plt.colorbar() plt.show() |
edgecolors指定なし | edgecolors指定あり |