Как изменить цветовую карту в радостном сюжете?

У меня есть кадр данных, который выглядит так:

  Team  Minute  Type
   148      12     1
   148      22     1
   143      27     1
   148      29     1
   143      32     1
   143      32     1

Я создал джойсюжет с помощью библиотеки Python joypy.

fig, axes = joypy.joyplot(df, by="Team", column="Minute", figsize =(10,16), x_range = [0,94], linewidth = 1, colormap=plt.cm.viridis)

Который дал мне этот сюжет:

введите здесь описание изображения

Все хорошо. Однако цветовая карта теперь бессмысленна, поэтому я пытаюсь раскрасить графики в соответствии со вторым кадром данных, который представляет собой сумму Type для всех команд.

Для этого я создал норму и карту цветов, используя следующие строки:

norm = plt.Normalize(group_df["Type"].min(), group_df["Type"].max())
cmap = plt.cm.viridis
sm = matplotlib.cm.ScalarMappable(cmap=cmap, norm=norm)
ar = np.array(group_df["Type"])
Cm = cmap(norm(ar))
sm.set_array([])

Вот где возникла проблема, так как я не могу понять, как изменить цвет джойплотов. Я попробовал несколько подходов:

  1. Я попытался передать это Cm в качестве аргумента цветовой карты. Однако выдало ошибку - typeerror 'numpy.ndarray' object is not callable

  2. Я попытался использовать цикл for для axes и Cm -

for col, ax in zip(Cm, axes):
    ax.set_facecolor(col)
    #ax.patch.set_facecolor(col) ##Also tried this; didn't change anything

Как я могу получить больший контроль над цветами джойплота и изменить их? Любая помощь будет оценена по достоинству.

MCVE

Образец CSV-файла, который я читаю (фактическая форма фрейма данных (4453,2)):

      Team  Minute
0      148       5
1      148       5
2      148      11
3      148      11
4      148      12
5      148      22
6      143      27

Мой код:

df = pd.read_csv(r"path")

##getting the sum for every team - total of 20 teams
group_df = df.groupby(["Team"]).size().to_frame("Count").reset_index()
  
df["Minute"] = pd.to_numeric(df["Minute"])

##Trying to create a colormap 
norm = plt.Normalize(group_df["Count"].min(), group_df["Count"].max())
cmap = plt.cm.viridis
sm = matplotlib.cm.ScalarMappable(cmap=cmap, norm=norm)
ar = np.array(group_df["Count"])
Cm = cmap(norm(ar))
sm.set_array([])


fig, axes = joypy.joyplot(df, by="Team", column="Minute", figsize =(10,16), x_range = [0,94], colormap = plt.cm.viridis)

Я хочу раскрасить каждый участок на графике общим количеством команды из значений group_df["Count"]. В настоящее время цветовая карта просто однородна, а не в соответствии с общим значением. На картинке выше то, что получилось.


person Abhishek    schedule 26.06.2019    source источник
comment
Возможно, вам удастся предоставить joyplot список цветов вместо палитры. Если нет, создание такого рода сюжетов может быть проще сделать вручную, когда у вас есть полный контроль над всем, а не только над цветами.   -  person ImportanceOfBeingErnest    schedule 26.06.2019
comment
Еще раз спасибо, похоже, что это может сработать. Как создать такой график вручную? Я думал, что Joypy был единственным доступным пакетом для создания джойплотов. Хотя мне все еще любопытно. Почему ax.set_facecolor() не работает; это ошибка?   -  person Abhishek    schedule 27.06.2019
comment
Например: здесь   -  person ImportanceOfBeingErnest    schedule 27.06.2019
comment
ax.set_facecolor() задает цвет осей, так что это не поможет. Причина, по которой вы не видите, что это имеет какой-либо эффект, заключается в том, что оси в любом случае отключены. Я могу помочь вам больше, если вы предоставите работающий пример (минимально воспроизводимый пример, Как сделать хорошие воспроизводимые примеры панд), которые я могу изменить.   -  person ImportanceOfBeingErnest    schedule 27.06.2019
comment
Я только что сделал это, это будет нормально? @ImportanceOfBeingErnest   -  person Abhishek    schedule 27.06.2019
comment
Если это возвращает оси, как мне получить дескриптор отдельных графиков?   -  person Abhishek    schedule 27.06.2019
comment
Передача списка цветов не сработала, так как для этого нет аргументов   -  person Abhishek    schedule 27.06.2019


Ответы (1)


joypy последовательно закрашивает кривые KDE цветами из палитры. Таким образом, чтобы цвета соответствовали третьей переменной, вы можете предоставить цветовую карту, содержащую цвета в нужном вам порядке. Это можно сделать с помощью ListedColormap.

import matplotlib
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(21)
import pandas as pd
import joypy

df = pd.DataFrame({"Team" : np.random.choice([143,148,159,167], size=200),
                   "Minute" : np.random.randint(0,100, size=200)})

##getting the sum for every team - total of 20 teams
group_df = df.groupby(["Team"]).size().to_frame("Count").reset_index()
print(group_df)



##Trying to create a colormap 
norm = plt.Normalize(group_df["Count"].min(), group_df["Count"].max())
ar = np.array(group_df["Count"])

original_cmap = plt.cm.viridis
cmap = matplotlib.colors.ListedColormap(original_cmap(norm(ar)))
sm = matplotlib.cm.ScalarMappable(cmap=original_cmap, norm=norm)
sm.set_array([])

fig, axes = joypy.joyplot(df, by="Team", column="Minute", x_range = [0,94], colormap = cmap)
fig.colorbar(sm, ax=axes, label="Count")

plt.show()

введите здесь описание изображения

person ImportanceOfBeingErnest    schedule 29.06.2019