Loading [MathJax]/jax/output/HTML-CSS/config.js

[matplotlib] 120. picture-jitter plot by sns.stripplot

matplotlib

はじめに

sns.stripplotではカテゴリ形式のデータの散布図をプロットすることができる。その際、プロットの重なりを抑えるために、プロットをランダムに横方向にずらしたプロットをジッタープロットという。ここでは、ジッタープロットのマーカーに画像を適用する例について紹介する。

コード&解説

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

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
sns.set(style="ticks", color_codes=True)
sns.set_context('talk')
view raw pic_jitter.py hosted with ❤ by GitHub

バージョン

#version
import matplotlib
print(matplotlib.__version__)
print(np.__version__)
print(pd.__version__)
print(sns.__version__)
3.5.2
1.23.1
1.4.3
0.11.2
view raw pic_jitter.py hosted with ❤ by GitHub

データの作成

np.random.seed(20220802)
#make data
df = pd.DataFrame({
'Zero': np.random.normal(3, 1, 10),
'One': np.random.normal(6, 1, 10),
'Two': np.random.normal(9, 1, 10)
})
view raw pic_jitter.py hosted with ❤ by GitHub

ランダムデータのDataFrameを作成する。表示すると以下のようになる。

df
"""
Zero One Two
0 3.543753 4.896810 8.812421
1 4.506194 4.554175 9.525765
2 4.428903 4.601120 10.290917
3 3.784704 6.459860 9.567849
4 3.368357 5.411275 8.369574
5 5.005184 4.726066 9.194902
6 1.175808 5.310682 8.218854
7 2.505475 5.869737 8.437992
8 2.721917 5.485696 8.318881
9 3.220280 6.246813 8.375657
"""
view raw pic_jitter.py hosted with ❤ by GitHub

sns.stripplotでジッタープロットを表示

fig, ax = plt.subplots(figsize=(6,6),dpi=100)
p = sns.stripplot(data=df,size=8, jitter=.1, ax=ax)
plt.savefig("sns_jitter_plot.png",dpi=130)
plt.show()
view raw pic_jitter.py hosted with ❤ by GitHub

stripplotで jitter=.1とすることでジッタープロットとなる。

stripplotからデータ取得

#stripplotからデータ取得
#https://stackoverflow.com/questions/32213889/get-positions-of-points-in-pathcollection-created-by-scatter
pos_0 = p.collections[0].get_offsets().data
pos_1 = p.collections[1].get_offsets().data
pos_2 = p.collections[2].get_offsets().data
view raw pic_jitter.py hosted with ❤ by GitHub

p.collections[0].get_offsets().dataのようにすることでstripplotで表示したデータを取得できる。

取得したデータは以下のような形式となっている。

pos_0,pos_0.shape
"""
(array([[-0.06958246, 3.54375323],
[-0.0882636 , 4.50619379],
[ 0.00532964, 4.42890309],
[ 0.03138891, 3.78470427],
[ 0.06900764, 3.36835661],
[ 0.07058994, 5.00518416],
[-0.04564606, 1.17580765],
[-0.01194475, 2.50547488],
[-0.04422985, 2.72191715],
[-0.02214219, 3.22028034]]),
(10, 2))
"""
view raw pic_jitter.py hosted with ❤ by GitHub

matplotlibのax.plot()で取得したデータを表示

# plt plotで表示
fig, ax = plt.subplots(figsize=(6,6),dpi=100)
ax.plot(pos_0[:,0],pos_0[:,1],"o")
ax.plot(pos_1[:,0],pos_1[:,1],"o")
ax.plot(pos_2[:,0],pos_2[:,1],"o")
ax.set_xlabel('variable')
ax.set_ylabel('value')
plt.savefig("plt_jitter_plot.png",dpi=130)
plt.show()
view raw pic_jitter.py hosted with ❤ by GitHub

ジッタープロットのマーカーを画像にして表示

画像をプロットする関数

def imscatter(x, y, image, ax=None, zoom=1):
if ax is None:
ax = plt.gca()
try:
image = plt.imread(image)
except TypeError:
# Likely already an array...
pass
im = OffsetImage(image, zoom=zoom)
x, y = np.atleast_1d(x, y)
artists = []
for x0, y0 in zip(x, y):
ab = AnnotationBbox(im, (x0, y0), xycoords='data', frameon=False)
artists.append(ax.add_artist(ab))
ax.update_datalim(np.column_stack([x, y]))
ax.autoscale()
return artists
view raw pic_jitter.py hosted with ❤ by GitHub

下記ページと同様の関数を用いる。

[matplotlib] 3.マーカーを画像にしてプロット
画像ファイルを読み込んでマーカーのかわりにプロットする方法について説明する。

画像ジッタープロットの表示

fig, ax = plt.subplots(figsize=(6,6),dpi=100)
x,y =pos_0.T
image_path = 'jam06_fig.png'#https://www.irasutoya.com/2014/09/blog-post_65.html
imscatter(x, y, image_path, ax=ax, zoom=.05)
ax.plot(x, y, 'ko',alpha=0)
x,y =pos_1.T
image_path = 'jam05_lemon.png' #https://www.irasutoya.com/2014/09/blog-post_65.html
imscatter(x, y, image_path, ax=ax, zoom=.05)
ax.plot(x, y, 'ko',alpha=0)
x,y =pos_2.T
image_path = 'jam04_apple.png' #https://www.irasutoya.com/2014/09/blog-post_65.html
imscatter(x, y, image_path, ax=ax, zoom=.05)
ax.plot(x, y, 'ko',alpha=0)
#ax.set_xlabel('variable')
ax.set_ylabel('value')
ax.set_xticks([0,1,2])
ax.set_xticklabels(["Zero","One","Two"])
ax.set_title("jitter=0.1")
plt.savefig("pic_jitter.png",dpi=130)
plt.show()
view raw pic_jitter.py hosted with ❤ by GitHub

画像は下記サイトから取得した。

いろいろなジャムのイラスト
いらすとやは季節のイベント・動物・子供などのかわいいイラストが沢山見つかるフリー素材サイトです。

jitter=0.3とした場合

p = sns.stripplot(data=df,size=8, jitter=.3, ax=ax)
pos_0 = p.collections[0].get_offsets().data
pos_1 = p.collections[1].get_offsets().data
pos_2 = p.collections[2].get_offsets().data
fig, ax = plt.subplots(figsize=(6,6),dpi=100)
x,y =pos_0.T
image_path = 'jam06_fig.png'#https://www.irasutoya.com/2014/09/blog-post_65.html
imscatter(x, y, image_path, ax=ax, zoom=.05)
ax.plot(x, y, 'ko',alpha=0)
x,y =pos_1.T
image_path = 'jam05_lemon.png' #https://www.irasutoya.com/2014/09/blog-post_65.html
imscatter(x, y, image_path, ax=ax, zoom=.05)
ax.plot(x, y, 'ko',alpha=0)
x,y =pos_2.T
image_path = 'jam04_apple.png' #https://www.irasutoya.com/2014/09/blog-post_65.html
imscatter(x, y, image_path, ax=ax, zoom=.05)
ax.plot(x, y, 'ko',alpha=0)
#ax.set_xlabel('variable')
ax.set_ylabel('value')
ax.set_xticks([0,1,2])
ax.set_xticklabels(["Zero","One","Two"])
ax.set_title("jitter=0.3")
plt.savefig("pic_jitter2.png",dpi=130)
plt.show()
view raw pic_jitter.py hosted with ❤ by GitHub
コードをダウンロード(.pyファイル)

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

参考

seaborn.stripplot — seaborn 0.13.2 documentation

コメント