Проблемы с представлением нечисловых (позиционных) рейтингов с pandas .plotting.parallel_coordinates - PullRequest
0 голосов
/ 03 мая 2020

Эта проблема заставляет меня ходить, как курица без головы, дольше, чем я хочу признать.

У меня есть рейтинг в кадре данных в следующем формате (Это краткий пример) .

+---------+-------+-------+-------+-------+-------+--+
| ranking | Day 1 | Day 2 | Day 3 | Day 4 | Day 5 |  |
+---------+-------+-------+-------+-------+-------+--+
| 1       | adria | adria | marta | marta | adria |  |
+---------+-------+-------+-------+-------+-------+--+
| 2       | marta | marta | dani  | dani  | marta |  |
+---------+-------+-------+-------+-------+-------+--+
| 3       | dani  | dani  | adria | adria | dani  |  |
+---------+-------+-------+-------+-------+-------+--+
| 4       | abel  | abel  | abel  | abel  | abel  |  |
+---------+-------+-------+-------+-------+-------+--+
| 5       |       | joan  | joan  |       |       |  |
+---------+-------+-------+-------+-------+-------+--+

Короче говоря, есть несколько игроков, которые go поднимаются и опускаются в рейтинге. Наконец, есть игрок ( Джоан ), который играет только два дня и исчезает.

Первым импульсом было использование pandas .plotting.parallel_coordinates (https://pandas.pydata.org/docs/reference/api/pandas.plotting.parallel_coordinates.html )

Со следующим кодом:

plt.figure(figsize = (20,5)) # Plot Width & Height
pd.plotting.parallel_coordinates(
  df, 'ranking',
  axvlines = False,
  marker='o', # Show marker
  markersize=12, #The Marker Size
  linewidth=6, # The Line Width
  alpha=0.9, # Opacity of lines
  )

plt.gca().invert_yaxis() # This inverts the Y aixs.
plt.legend('')
plt.style.use('fivethirtyeight') # This is the style
plt.show()

Но результат совсем не тот, что ожидался:

Ссылка на изображение: ссылка

Обратите внимание, что я перевернул ось Y, чтобы представить позицию №1 выше

Проблема № 1: Строки не соответствуют порядку таблицы. Как видите, игрок " dani " никогда не попадает на первую позицию, но в представлении вы увидите, что он поднимается на две позиции в рейтинге вверх. Если вы сравните данные в таблице с визуализацией, то же самое произойдет и с другими игроками. Они не следуют позициям таблицы.

Задача № 2: Я не знаю, как изобразить Джоан . Строка должна представлять только дни, в которые он играл.

Задача № 3: Это очень простая визуализация, но давайте представим, что у нас есть сотни игроков за много дней. Это может усложнить отслеживание цветов. Я думал о том, чтобы поставить имя игрока в качестве метки на каждой из точек линий, но я не смог найти метод ...

Мои гипотезы варьируются от простого факта, что Я бесполезен (преобладает бритва Оккама) , так что невозможно представить эти данные таким образом с помощью этой библиотеки.

Я испытывал желание попробовать использовать что-то похожее на Диаграмма Санки для этого ... но я не думаю, что это именно то, что мне нужно, и это сильно усложняет код.

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

Любые идеи будут приветствоваться.

Спасибо!

1 Ответ

0 голосов
/ 04 мая 2020

Я не знаю, как сделать это в самом pandas, но возможно сделать что-то подобное в Altair , если вы сначала melt в своем DataFrame:

import altair as alt

alt.Chart(
    df.melt("ranking", var_name="day", value_name="player").dropna()
    , width=500
).mark_line(
    strokeWidth=5,
    opacity=0.5
).encode(
    alt.X('day:N', title=""),
    alt.Y('ranking:Q', scale=alt.Scale(domain=[1, 5], reverse=True)),
    color='player:N',
    tooltip='player:N',
)

Что дает вам: enter image description here

Или вы можете добавить текст к каждой точке на графике, например:

import altair as alt

base = alt.Chart(
    df.melt("ranking", var_name="day", value_name="player").dropna()
    , width=500
).encode(
    alt.X('day:N', title=""),
    alt.Y('ranking:Q', scale=alt.Scale(domain=[1, 5], reverse=True)),
)

base.mark_line(
    strokeWidth=5,
    opacity=0.5
).encode(
    color='player:N',
    tooltip='player:N',
) + base.mark_text(
    fontSize=16
).encode(
    text='player:N'
)

enter image description here

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