График 1D-данные в 2D с дискретными значениями по оси X в виде меток в Python

#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) удаляет все линии сетки