はじめに
sns.stripplotではカテゴリ形式のデータの散布図をプロットすることができる。その際、プロットの重なりを抑えるために、プロットをランダムに横方向にずらしたプロットをジッタープロットという。ここでは、ジッタープロットのマーカーに画像を適用する例について紹介する。
コード&解説
モジュールのインポートなど
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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')
バージョン
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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
データの作成
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)
})
ランダムデータのDataFrameを作成する。表示すると以下のようになる。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
"""
sns.stripplotでジッタープロットを表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()
stripplotで jitter=.1とすることでジッタープロットとなる。

stripplotからデータ取得
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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
p.collections[0].get_offsets().dataのようにすることでstripplotで表示したデータを取得できる。
取得したデータは以下のような形式となっている。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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))
"""
matplotlibのax.plot()で取得したデータを表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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()

ジッタープロットのマーカーを画像にして表示
画像をプロットする関数
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
下記ページと同様の関数を用いる。

[matplotlib] 3.マーカーを画像にしてプロット
画像ファイルを読み込んでマーカーのかわりにプロットする方法について説明する。
画像ジッタープロットの表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()
画像は下記サイトから取得した。

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

jitter=0.3とした場合
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()

参考
seaborn.stripplot — seaborn 0.13.2 documentation
コメント