сюжет не добавляет легенды - PullRequest
0 голосов
/ 12 апреля 2020

Я использую plotnine для построения двух графиков на одном графике. один график использует значения 'b' из кадра данных, который вы увидите ниже, а другой график использует значения из 'c'.

Все, что мне нужно, это показать простую легенду, где я вижу " c 'и' b 'с соответствующим цветом.

def plot_log_detected():
    df = DataFrame({'x': [1, 2, 3, 4, 5],
                    'b': >>>SOME VALUES DOESNT MATTER<<<,
                    'c': >>>SOME VALUES DOESNT MATTER<<<
                   })
    return ggplot(aes(x='x', y='b'), data=df) + geom_point(size=1) +\
           geom_line(aes(y='b'), color='black') + \
           geom_line(aes(y='c'), color='blue') +  \
           ggtitle("TITLE") + \
           labs(y="Y AXIS", x="X AXIS")

Ответы [ 2 ]

1 голос
/ 13 апреля 2020

Легенда не будет отображаться, если вы также используете ggplot2 в R: легенда для цвета будет представлена, только если вы укажете color= в эстетике c для geom. «Исправление» одинаково в python или ggplot для r. Вы должны организовать свои данные так, чтобы вы следовали принципам аккуратные данные . В этом случае каждый столбец df$b и df$c содержит две части информации: (1) значение для "y" и (2) тип для "y". Вы должны соответствующим образом реорганизовать данные так, чтобы имена ваших столбцов стали такими: x, type_of_y и value_of_y.

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

Основы

Вот набор данных и график, похожий на ваш график (опять же, он находится в r ... Итак, я надеюсь, что вы можете перевести в python):

df <- data.frame(
    x=c(1:5), b=c(10, 12, 14, 9, 8), c=c(9, 11, 11, 12, 14))

ggplot(df, aes(x=x)) +
    geom_line(aes(y=b), color='red') +
    geom_line(aes(y=c), color='blue')

enter image description here

Нет легенды, но цвета есть, и мы строим то, что вы ожидаете. Проблема здесь в том, что ggplot dr aws легенда, когда вы задаете цвет в вызове aes(). Чтобы это ясно увидеть, давайте просто сделаем тот же график, но переместим color=... внутрь aes():

ggplot(df, aes(x=x)) +
    geom_line(aes(y=b, color='red')) +
    geom_line(aes(y=c, color='blue'))

enter image description here

Хорошо, это ... подождите. Какая? Теперь у него есть легенда (потому что мы поместили color внутри aes()), но цвета на самом деле меняются местами по порядку, и ... вы заметите, что цвета не красные и синие, а по умолчанию цвета "reddi sh" и "teal" ggplot2. На самом деле произошло то, что мы только указали, что при первом вызове geom_line мы построили правильный набор данных, но мы только «назвали» данные как «красные». Аналогично, мы назвали другой набор данных «синим». ggplot решил, какие цвета использовать, основываясь на палитре по умолчанию.

Получение легенды без аккуратных данных

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

ggplot(df, aes(x=x)) +
    geom_line(aes(y=b, color='b')) +
    geom_line(aes(y=c, color='c'))

enter image description here

Как насчет просто добавив еще один color='blue', чтобы получить "синий" цвет снаружи aes(), а также внутри? Ну ... это не работает. Если вы сделаете это, например, результат будет идентичен показанному исходному графику (без легенды, но с правильными значениями цвета), поскольку aes() эффективно перезаписывается при каждом вызове geom_line:

# this doesn't work to keep legend and desired color, the second
# color outside aes() overwrites the one inside aes()
ggplot(df, aes(x=x)) +
    geom_line(aes(y=b, color='b'), color='red') +
    geom_line(aes(y=c, color='c'), color='blue')

Tidy Data Way («правильный» способ)

Хотя вышеуказанный метод работает, он идет вразрез с общими принципами Tidy Data и с тем, как организовать ваши данные так, чтобы их было легко анализировать ... любым способом, который вы хотите. Поверьте мне: это определенно лучшая практика для работы с любым набором данных для универсальности анализа и почти всегда стоит усилий для организации ваших данных таким образом.

ggplot хочет указать aes() параметры в виде столбцов в наборе данных . Это означает, что мы должны сделать так, чтобы каждый столбец служил определенной c цели в вашем наборе данных следующим образом:

  • x: Это то же самое x в оригинале набор данных. Он представляет собой только значение оси x

  • type_of_y: этот столбец содержит значение «b» или «c», указывающее, к какой серии данных значения должны быть от.

  • value_of_y: этот столбец содержит значение, которое вы бы построили на y.

Использование dplyr, мы можем довольно просто реорганизовать данные:

df <- df %>% gather('type_of_y', 'value_of_y', -x)

Давать вам:

   x type_of_y value_of_y
1  1         b         10
2  2         b         12
3  3         b         14
4  4         b          9
5  5         b          8
6  1         c          9
7  2         c         11
8  3         c         11
9  4         c         12
10 5         c         14

Затем вы строите график соответственно, используя только один вызов geom_line и применяете color эстетика c до type_of_y. Примерно так:

ggplot(df, aes(x=x, y=value_of_y)) +
    geom_line(aes(color=type_of_y))

enter image description here

Таким образом, вам нужно указать только один geom_line вызов. Может показаться, что это не так уж и отличается, но что если у вас есть несколько столбцов в исходном наборе данных? Возьмем, к примеру, случай с «x», тогда значения y для «a», «b», «c» ... «z»! Вы должны будете указать все эти строки в отдельных вызовах на geom_line! В приведенном выше случае, независимо от того, сколько у вас было разных столбцов значений y ... у вас есть только те же две строки кода и только один вызов geom_line. Есть смысл? Для получения дополнительной информации, я бы предложил ссылку сверху. Кроме того, эта статья отлично подходит для чтения.

Затем можно назначить определенные c цвета, добавив scale_color_manual и указав цвета таким образом (есть также несколько других способов) - но если вам нужна помощь там, я бы задал отдельный вопрос. Также ... не уверен, как код отличается для python. Точно так же вы можете изменить заголовок легенды через labs(color="your new legend title") ... среди других изменений темы.

Я знаю, что это не совсем тот же код в python, но этого должно быть достаточно для того, чтобы вы вычислили наш как там это сделать аналогично.

0 голосов
/ 13 апреля 2020

Вы можете объединить ваш фрейм данных, чтобы объединить столбцы 'b' и 'c' в один столбец и создать эстетический столбец c color для раскраски и легенды. Вот код и вывод. Обратите внимание, что я использовал исходный фрейм данных для точечного графика (поскольку в этом случае вы строите только столбец 'b') и использовал расплавленный фрейм данных для линейного графика:

def plot_log_detected():
    df = DataFrame({'x': [1, 2, 3, 4, 5],
                    'b': [1, 2, 3, 4, 5],
                    'c': [1, 3, 2, 5, 4]
                   })

    df_melt = df.melt(id_vars=['x'], value_vars=['b','c'], var_name='color', value_name='b_and_c')

    return ggplot(aes(x='x', y='b'), data=df) + geom_point(size=1) +\
           geom_line(aes(y='b_and_c', color='color'), data=df_melt) + \
           ggtitle("TITLE") + \
           labs(y="Y AXIS", x="X AXIS")

Ваш оригинальный примерный фрейм данных выглядит следующим образом:

   x  b  c
0  1  1  1
1  2  2  3
2  3  3  2
3  4  4  5
4  5  5  4

И ваш расплавленный кадр данных:

   x color  b_and_c
0  1     b        1
1  2     b        2
2  3     b        3
3  4     b        4
4  5     b        5
5  1     c        1
6  2     c        3
7  3     c        2
8  4     c        5
9  5     c        4

И, наконец, это выходное изображение:

enter image description here

...