はじめに
seaborn の markers
を指定した際にエラーが出たため、調査しました。
書籍「pandasライブラリ活用入門」の「3.4.3.2 サイズと形」の2番目のプロットが動作しなかった経緯があります。1番目の図についてはこちらに記事を書きました。
現象
markers
と style
を指定することにより、カテゴリ変数の値によってマーカーを出し分けることができます。(書籍では style
の指定がなく動作しなかったため追加しました。また説明のためにsize
は除いています。)
しかし、下記のように['o', 'x']
を指定するとエラーになってしまいます。
import seaborn as sns
from matplotlib import pyplot as plt
tips = sns.load_dataset('tips')
sns.scatterplot(
data=tips,
x='total_bill',
y='tip',
hue='sex',
style='sex',
markers=['o', 'x'],
)
plt.show()
ValueError: Filled and line art markers cannot be mixed
解決策
エラーが示すように、filled marker と line art marker は混在できません。後述するように、'o'
は filled、'x'
は line art なのでエラーとなります。'x'
に似た filled marker は 'X'
(xの大文字)なので、これに変更すると思ったように動作します。
import seaborn as sns
from matplotlib import pyplot as plt
tips = sns.load_dataset('tips')
sns.scatterplot(
data=tips,
x='total_bill',
y='tip',
hue='sex',
style='sex',
markers=['o', 'X'], # ← 変更
)
plt.show()
marker の一覧
seaborn で使用可能なマーカーは matplot に準じるので、matplotlib で探します。
from matplotlib.markers import MarkerStyle
ms = MarkerStyle()
# filled_marker を取得
filled_markers = ms.filled_markers
# すべての marker を取得
all_markers = tuple(ms.markers.keys())
# すべての marker から filled marker を除外
non_filled_markers = tuple(filter(lambda mk: mk not in filled_markers, all_markers))
print(filled_markers)
#→ ('o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd', 'P', 'X')
print(non_filled_markers)
#→ ('.', ',', '1', '2', '3', '4', '+', 'x', '|', '_', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 'None', None, ' ', '')
繰り返しですが filled marker と line art marker (non_filled_markers
)は混在できません。
どちらか片方のセットからマーカーを選ぶことになります。