#python #pandas #matplotlib #seaborn
#python #панды #matplotlib #seaborn
Вопрос:
У меня есть следующий фрейм данных
it, A B C D
0 10, aa mn cd kk
1 100, ab cd wc ll
2 1000, wc cd mn sf
3 10000, ll ll kk mn
4 100000, wc kk mn cd
5 1000000, aa ll we sf
6 10000000, 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
Цель состоит в том, чтобы создать диаграмму рассеяния, где по оси y представлены уникальные значения из фрейма данных в отсортированном порядке, например, параметры, а ось a соответствует столбцу. it
Теперь в зависимости от того, принадлежат ли данные столбцу A, B, C,
, или D
я хочу по-разному раскрасить точки рассеяния и указать легенду. Итак, я знаю, из какого класса происходит точка.
Как мне это сделать в seaborn или matplotlib?
То, как я делаю это в matplotlib,
iters = list(range(df.shape[0]))
x, y = sort(iters, df["A"])
plt.scatter(x, y, color="red")
x, y = sort(iters, df["B"])
plt.scatter(x, y, color="blue")
...
но это сортирует не всю ось y, а только метки, принадлежащие отдельным столбцам.
Ответ №1:
Давайте попробуем сложить данные, преобразовать в категориальный с заданным порядком, отсортировать и построить график:
s = df.stack()
s = pd.Series(pd.Categorical(s, categories=options, ordered=True),
index=s.index)
sns.scatterplot(data=s.sort_values().reset_index(name='value'),
x='level_0', y='value', hue='level_1'
)
Вывод:
Обновление: если у вас есть столбец xvalue
и вам нужны только некоторые столбцы ['A','B','C','D']
, используйте melt
вместо stack
:
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'
)
Комментарии:
1. Но это не выглядит отсортированным! ось x должна быть осью y, но это не большая проблема. Проблема в том, что ось x не отсортирована, по крайней мере, для matplotlib
2. @YohanRoth Я пропустил
options
часть. Смотрите Обновленный ответ.3. итак, ваше решение не работает в моем случае, это моя вина, я неправильно указал проблему. в дополнение к столбцу A, B, C, D у меня есть еще один столбец, в котором указаны значения по оси x, которые не являются просто строками (у них большие пробелы, такие как 1, 10, 1000, 10000) и т.д. Не могли бы вы показать мне, как изменить ответ, чтобы учесть это? В любом случае я приму это! Я обновил проблему
4. Я получаю ошибку ValueError: длина значений (3) не соответствует длине индекса (28) для s[‘value’] = pd.Categorical(s, categories= options, ordered= True)
5. s.shape (28, 3) pd.Категориальный (3,)