Назначьте разные маркеры, размер, границы и непрозрачность в диаграмме рассеяния seaborn

#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)