Loading [MathJax]/extensions/tex2jax.js

[matplotlib] 97. plt.scatterで離散的カラーバーを表示

matplotlib

はじめに

散布図を作成できるmatplotlibのplt.scatterで点の色を変えて表示する場合、その色が示すものを説明する必要がある。そこで離散的なカラーバーとともに散布図を表示する方法について説明する。

コード

from sklearn.cluster import KMeans
from sklearn.datasets import make_moons
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
from matplotlib.colors import BoundaryNorm
import numpy as np
# Generate sample data
n_samples = 1000
noise = .04
X,y = make_moons(n_samples=n_samples,noise=noise)
#n_clusters=10
n_clusters=10
kmeans_model_10 = KMeans(n_clusters)
fit_10 =kmeans_model_10.fit(X)
y_10_ = fit_10.labels_
levels = MaxNLocator(nbins=10).tick_values(0,10)-.0001
cmap = plt.get_cmap('turbo')
norm = BoundaryNorm(levels, ncolors=cmap.N, clip=True)
fig, ax = plt.subplots(dpi=140,figsize=(6,5))
ax.axis("equal")
ax.set(xlabel="x",ylabel="y")
p=ax.scatter(X[:,0],X[:,1], c=y_10_,marker='o',alpha=1,s=55,linewidths=.1,edgecolor="k",cmap="turbo",norm=norm)
ax.scatter(fit_10.cluster_centers_[:,0],fit_10.cluster_centers_[:,1],s=60, marker='D',c='pink')
ax.set_title("n_clusters=10")
cbar = plt.colorbar(p,ticks=np.arange(10)+.5)
cbar.ax.set_yticklabels(np.arange(10))
plt.savefig("kmeans_2_3.png",dpi=100)
plt.show()
view raw kmeans_2.py hosted with ❤ by GitHub

解説

モジュールのインポートなど

from sklearn.cluster import KMeans
from sklearn.datasets import make_moons
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
from matplotlib.colors import BoundaryNorm
import numpy as np
view raw kmeans_2.py hosted with ❤ by GitHub

バージョン

#version
import matplotlib
print(matplotlib.__version__)
3.3.4
import sklearn
print(sklearn.__version__)
0.24.1
print(np.__version__)
1.20.1
view raw kmeans_2.py hosted with ❤ by GitHub

データの生成

# Generate sample data
n_samples = 1000
noise = .04
X,y = make_moons(n_samples=n_samples,noise=noise)
view raw kmeans_2.py hosted with ❤ by GitHub

sklearnのdatasets.make_moonsで三日月状の分布を示すクラスタリング、分類用のデータを作成する。詳細は下記記事で解説した。Xにデータの座標が入り、yにラベルの値が入る。

[scikit-learn] 4. make_moonsによる三日月状データの生成
sklearnのdatasets. make_moonsで三日月状の分布を示すクラスタリング、分類用のデータを作成することができる。ここでは各種パラメータが生成データに及ぼす影響について説明する。

図示すると以下のようになる。

fig, ax = plt.subplots(dpi=140,figsize=(5,5))
ax.axis("equal")
plt.scatter(X[:, 0], X[:, 1], c=y, marker='o',alpha=0.5,s=55,linewidths=.1,edgecolor="k",cmap="turbo")
ax.set(xlabel="x",ylabel="y")
plt.savefig("kmeans_2_1.png",dpi=100)
plt.show()
view raw kmeans_2.py hosted with ❤ by GitHub

KMeansによるクラスタリング

n_clusters=10
kmeans_model_10 = KMeans(n_clusters)
fit_10 =kmeans_model_10.fit(X)
y_10_ = fit_10.labels_
view raw kmeans_2.py hosted with ❤ by GitHub

クラスター数を10として、k平均法によるクラスタリングを行う。y_10_はそれぞれのデータをクラスタリングした結果(ラベル)となる。

離散的カラーバーのための準備

levels = MaxNLocator(nbins=10).tick_values(0,10)-.0001
cmap = plt.get_cmap('turbo')
norm = BoundaryNorm(levels, ncolors=cmap.N, clip=True)
view raw kmeans_2.py hosted with ❤ by GitHub

レベルを設定する。値がレベルの範囲内におさまるように全体から-.0001している。
BoundaryNormでレベルに基づいて、カラーマップインデックスを生成する。

離散的カラーバーつき散布図の表示

fig, ax = plt.subplots(dpi=140,figsize=(6,5))
ax.axis("equal")
ax.set(xlabel="x",ylabel="y")
p=ax.scatter(X[:,0],X[:,1], c=y_10_,marker='o',alpha=1,s=55,linewidths=.1,edgecolor="k",cmap="turbo",norm=norm)
ax.scatter(fit_10.cluster_centers_[:,0],fit_10.cluster_centers_[:,1],s=60, marker='D',c='pink')
ax.set_title("n_clusters=10")
cbar = plt.colorbar(p,ticks=np.arange(10)+.5)
cbar.ax.set_yticklabels(np.arange(10))
plt.savefig("kmeans_2_3.png",dpi=100)
plt.show()
view raw kmeans_2.py hosted with ❤ by GitHub

ax.scatter()でnorm=normとする。
各クラスター中心はax.scatter(fit_10.cluster_centers_[:,0],fit_10.cluster_centers_[:,1])で表示した。
カラーバーはplt.colorbar(p,ticks=np.arange(10)+.5)として、目盛りの値が各カラーの真ん中に来るように+0.5とした。目盛りの値はcbar.ax.set_yticklabels()で設定できる。

コードをダウンロード(.pyファイル)

コードをダウンロード(.ipynbファイル)

参考

matplotlib.pyplot.colorbar — Matplotlib 3.3.4 documentation
KMeans
Gallery examples: Release Highlights for scikit-learn 1.1 Release Highlights for scikit-learn 0.23 A demo of K-Means clu...

コメント