Управление цветом, условные обозначения при построении графиков из Pandas DataFrame с несколькими значениями y для каждого x - PullRequest
0 голосов
/ 10 мая 2018

У меня есть датафрейм с 3 столбцами. Я хотел бы построить col1 на оси x с col2 и col3 на оси y. Col1 имеет повторяющиеся значения, поэтому для каждого значения x есть повторяющиеся значения y.

Пример кадра данных:

DF = pd.DataFrame({"name": ["Alice", "Alice", "Charles", "Charles", "Kumar", "Kumar"],
              "height": [124, 126, 169, 170, 175, 174],
              "weight": [100, 105, 123, 125, 139, 140]})

DF 

    name    height  weight
  0 Alice   124     100
  1 Alice   126     105
  2 Charles 169     123
  3 Charles 170     125
  4 Kumar   175     139
  5 Kumar   174     140

Я хочу:

А) каждый человек встречается только один раз по оси х

B) сохранить все высоты одним цветом, а все веса - другим цветом с точной неповторяющейся легендой

Пока что я могу получить либо А, либо В, но не оба. Ниже то, что я пытаюсь и вывод. Для A это было полезно ( Диаграмма рассеяния Python с несколькими значениями Y для каждого X )

Для A:

f = DF.groupby("name", as_index=False).agg({"height":lambda x: tuple(x), "weight":lambda x: tuple(x)})
for x, (y1, y2) in enumerate(zip(f.height.values.tolist(), f.weight.values.tolist()), start=1):

    plt.scatter([x] * len(y1), y1, color='green', marker='o', label="height")
    plt.scatter([x] * len(y2), y2, color='blue', marker='o', label="weight")

plt.xticks(np.arange(1, len(f.name.values) +1))
plt.axes().set_xticklabels(f.name.values.tolist())
plt.legend(loc="best")
plt.show()

Для B:

ax = DF.plot(style="o", figsize=(7, 5), xlim=(-1, 6))
ax.set_xticks(DF.index)
ax.set_xticklabels(DF.name, rotation=90)
plt.show()

enter image description here

enter image description here

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Поскольку у вас есть 2 столбца, вы можете построить 2 точечных графика, каждый со своим собственным ярлыком.

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({"name": ["Alice", "Alice", "Charles", "Charles", "Kumar", "Kumar"],
              "height": [124, 126, 169, 170, 175, 174],
              "weight": [100, 105, 123, 125, 139, 140]})

plt.scatter(df.name, df.height, label="height")
plt.scatter(df.name, df.weight, label="weight")
plt.legend()
plt.show()

enter image description here

Имея больше столбцов, вы, конечно, можете зацикливаться на них

for col in ["height", "weight"]:
    plt.scatter(df.name, df[col], label=col)
0 голосов
/ 10 мая 2018

Один простой вариант - построить график напрямую с помощью matplotlib вместо использования метода pandas.DataFrame.plot. Чтобы иметь решение, независимое от числа столбцов и строк и т. Д., Столбец «имя» может быть установлен в индекс. Нет необходимости перебирать столбцы. Таким образом, код будет:

DF.set_index('name',inplace=True)
plt.plot(DF.index,DF.values,'o')
plt.legend(DF.columns)

Который генерирует:

plot1

Еще одна альтернатива - адаптировать параметр B, заменив строковые значения (которые не используются для построения графика, а вместо индекса, поэтому они не находятся в одном месте) на целочисленные значения.

x_labels = DF['name'].drop_duplicates()
map_x_vals = {v: k for k, v in x_labels.to_dict().items()}
ax = DF.replace({'name' : map_x_vals}).plot(x='name',style="o", figsize=(7, 5), xlim=(-1, 6))
ax.set_xticks(x_labels.index)
ax.set_xticklabels(x_labels.values, rotation=90)
plt.show()

Чтобы получить хорошее отображение, используется обратное отображение между индексом и именем после удаления дубликатов, а для тиков и тиклбэков используются те же значения.

Обратите внимание, что замена выполняется перед графиком и не сохраняется, поэтому DF не изменяется.

Сгенерированный участок выглядит следующим образом:

plot2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...