#python #matplotlib #seaborn
#python #matplotlib #seaborn
Вопрос:
У меня есть следующий фрейм данных
xvalue, A B C D
0 10, aa mn cd kk
1 20, ab cd wc ll
2 30, wc cd mn sf
3 40, ll ll kk mn
4 50, wc kk mn cd
5 60, aa ll we sf
6 70, ss aa ss kk
Код для ее создания
options = ["ab", "cd", "bb", "aa", "we", "ss", "kk", "mn", "re", "wc", "ll", "sf"]
df = pd.DataFrame(columns=["A", "B", "C", "D"])
for i, it in enumerate([1,2,3,4,5,6,7]):
row = [10*i, random.sample(options, 1)[0], random.sample(options, 1)[0],
random.sample(options, 1)[0], random.sample(options, 1)[0]]
df.loc[i] = row
И построение графика завершено
s = df.melt(id_vars='xvalue',
value_vars=['A','B','C','D'],
value_name='value',
var_name='column')
s['value'] = pd.Categorical(s['value'], categories=options, ordered=True)
sns.scatterplot(data=s.sort_values('value'), x='xvalue', y='value', hue='column')
Теперь вопрос — как мне назначить разные стили точечным точкам, которые принадлежат к разным классам (например, определяемым столбцами). A, B, C, D
Например, я хочу, чтобы класс A был маркером «P», B — маркером «p», C — маркером «v». То же самое я хочу определить альфа (непрозрачность), линию границы, указать цвет и т.д.
В matplotlib я бы сделал
plt.scatter(x, y, color="blue", label="A", alpha=0.8, s=80, marker="p")
Но это явно создало бы другой график на графике с его собственными параметрами. Прямо сейчас я не знаю, как работать с разными классами в рамках «одного графика».
Я также пытался
markers = {"A": "s", "B": "X", "C": "p", "D":"o"}
sns.scatterplot(data=s.sort_values('value'), x='xvalue', y='value', hue='column', markers=markers)
Но это не дало никакого эффекта.
РЕДАКТИРОВАТЬ: чтобы применить разные маркеры, я должен указать style=»column», но если я попытаюсь
sizes = {"A":100, "B": 120, "C": 150, "D":200}
sns.scatterplot(data=s.sort_values('value'), x='xvalue', y='value', hue='column', markers=markers, s=sizes)
Это не работает
Комментарии:
1. Вы можете изменять маркеры в разных классах с
style='column'
помощью, но вы не можете делать это по отдельности, например, прозрачность и цвет.2. @r-новички, если я использую style=’column», я могу применять разные маркеры, но не разные размеры, буквы, границы и т. Д. Как мне этого добиться?
Ответ №1:
Другой способ — заменить строки / значения options
перечислением:
opt_dict = {opt:i for i,opt in enumerate(options)}
markers = {"A": "s", "B": "X", "C": "p", "D":"o"}
sizes = {"A":100, "B": 120, "C": 150, "D":200}
alphas = {'A':0.2, 'B':0.3, 'C':0.6, 'D':0.8}
col_list = ['A','B','C','D']
fig, ax = plt.subplots(figsize=(9,6))
for col in col_list:
ax.scatter(df['xvalue'], df[col].map(opt_dict),
marker=markers[col],
s=sizes[col],
alpha=alphas[col],
label=col)
ax.set_yticks(range(len(options)))
ax.set_yticklabels(options)
ax.legend()
Вывод:
Комментарии:
1. к сожалению, этот подход удаляет упорядоченный порядок!
2. @YohanRoth ось y показывает правильный порядок, не так ли?
3. @YohanRoth разве вы не хотите отображать их в порядке
options
?4. Извините, если это было непонятно, но нет, я хочу, чтобы «параметры» были по оси y, но в отсортированном порядке. Теперь я делаю cats = sorted(s[«value»].unique()) s[‘value’] = pd.Categorical(s[‘value’], categories= cats, ordered=True)