#python #pandas #matplotlib #seaborn
Вопрос:
У меня есть csv-файл с 15 строками, каждая из которых содержит 50 значений, т. е. 50 столбцов. В первой строке, то есть в заголовке, есть метки/имена значений.
Файл выглядит так (заполнено 50 столбцов, 15 строк, некоторые значения nan):
label1, label2, label3, ..., label50
0123, 345, nan, ..., 287
4324, nan, 343, ..., 362
...
Я хочу построить значения каждого столбца по вертикали.
Для 15 строк, включая заголовок = 14 значений на одном горизонтальном значении x (которое является меткой).
Так что моя ось X дискретна с именами меток в качестве значений.
Один из подходов, который работал, но работает только для коробочных диаграмм, а не точек рассеяния, заключается в следующем (изображения см. https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.boxplot.html):
df = pd.read_csv("data.csv", delimiter=",")
df.plot.box() # plots boxplot with discrete x-axis values as labels
plt.xticks(rotation=90, ha='right') # label names are 90 degree turned on x-axis
plt.yscale(log) # logscale for my dataset
plt.show()
Я хотел бы получить тот же результат, что и на графике. Но вместо полей я хочу видеть каждую точку столбцов вертикально распределенными и, если возможно, каждую строку csv в уникальном цвете, чтобы отделить строки друг от друга на диаграмме. (Одна строка-это одна «комбинация» точек данных)
Как новичок, я еще не нашел решения…
Заранее большое спасибо. Не стесняйтесь спрашивать, когда вы не поняли моего объяснения.
Комментарии:
1. Спасибо за ваш ответ! Я добавил столбец «Имя» в свой csv-файл. Раскрашивание работает! Но мне не нужны линии, а вместо этого мне нужны точки. Знаете ли вы способ построить его с помощью точек вместо линий?
Ответ №1:
Вы могли бы попробовать панд» parallel_coordinates
. Вам нужно будет добавить дополнительный столбец, чтобы придать каждой строке уникальную метку. Вы можете удалить лайнстайл и использовать точку в качестве маркера:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(1, 100, (15, 50)).astype(float), columns=[f'lbl{i}' for i in range(1, 51)])
df['Name'] = [f'row{i}' for i in range(len(df))]
fig, ax = plt.subplots(figsize=(25, 8))
pd.plotting.parallel_coordinates(df, 'Name', color=plt.cm.tab20(np.arange(len(df))), ls='', marker='o', ax=ax)
ax.legend(bbox_to_anchor=(1.01, 1.02), loc='upper left')
plt.tight_layout()
plt.show()
PS: Вы можете использовать pd.plotting.parallel_coordinates(..., axvlines=False)
и ax.grid(False, axis='x')
, если вертикальные линии не нужны. ax.tick_params(axis='x', rotation=30)
повернул бы x-метки на 30 градусов.
Вот еще один пример, который также устанавливает некоторое поле слева и справа.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(1, 10, (15, 50)).astype(float).cumsum(axis=0), columns=[f'lbl{i}' for i in range(1, 51)])
df['Name'] = [f'row{i}' for i in range(len(df))]
fig, ax = plt.subplots(figsize=(15, 8))
pd.plotting.parallel_coordinates(df, 'Name', color=plt.cm.turbo(np.linspace(0, 1, len(df)) ), ls='', marker='o', axvlines=False, ax=ax)
ax.legend(bbox_to_anchor=(1.01, 1.02), loc='upper left')
ax.grid(False)
ax.tick_params(axis='x', rotation=30)
ax.autoscale()
ax.margins(x=0.01)
plt.tight_layout()
plt.show()
Комментарии:
1. Спасибо! Это и есть решение. У меня был бы еще один вопрос: как я могу удалить горизонтальные линии сетки? 😀
2.
ax.grid(False)
удаляет все линии сетки