Две geom_points добавляют легенду

Я построю график с двумя геометрами с следующим кодом:

source("http://www.openintro.org/stat/data/arbuthnot.R")
library(ggplot2)
ggplot() +
  geom_point(aes(x = year,y = boys),data=arbuthnot,colour = '#3399ff') +
  geom_point(aes(x = year,y = girls),data=arbuthnot,shape = 17,colour = '#ff00ff') +
  xlab(label = 'Year') +
  ylab(label = 'Rate')

Я просто хочу знать, как добавить легенду с правой стороны. С той же формой и цветом. Треугольник розовый должен иметь легенду "женщина" и синий круг легенды "мужчины". Кажется довольно простым, но после многих испытаний я не мог этого сделать. (Я начинаю с ggplot).

enter image description here

Ответ 1

Если вы переименуете свои столбцы исходного фрейма данных и затем расплавите его в длинный формат с помощью reshape2::melt, его гораздо проще обработать в ggplot2. Указав эстетику color и shape в команде ggplot и указав масштаб для цветов и фигур вручную, появится легенда.

source("http://www.openintro.org/stat/data/arbuthnot.R")
library(ggplot2)
library(reshape2)

names(arbuthnot) <- c("Year", "Men", "Women")

arbuthnot.melt <- melt(arbuthnot, id.vars = 'Year', variable.name = 'Sex', 
    value.name = 'Rate')

ggplot(arbuthnot.melt, aes(x = Year, y = Rate, shape = Sex, color = Sex))+
geom_point() + scale_color_manual(values = c("Women" = '#ff00ff','Men' = '#3399ff')) + 
scale_shape_manual(values = c('Women' = 17, 'Men' = 16))

enter image description here

Ответ 2

Вот способ сделать это без использования reshape :: melt. reshape :: melt работает, но вы можете войти в привязку, если хотите добавить другие вещи в график, такие как отрезки. Код ниже использует оригинальную организацию данных. Ключ к изменению легенды - убедиться, что аргументы scale_color_manual (...) и scale_shape_manual (...) идентичны, иначе вы получите две легенды.

source("http://www.openintro.org/stat/data/arbuthnot.R")
library(ggplot2)
library(reshape2)



ptheme <- theme (
  axis.text            = element_text(size = 9),              # tick labels
  axis.title           = element_text(size = 9),              # axis labels
  axis.ticks           = element_line(colour = "grey70", size = 0.25),
  panel.background     = element_rect(fill = "white", colour = NA),
  panel.border         = element_rect(fill = NA, colour = "grey70", size = 0.25),
  panel.grid.major     = element_line(colour = "grey85", size = 0.25),
  panel.grid.minor     = element_line(colour = "grey93", size = 0.125),
  panel.margin         = unit(0 , "lines"),
  legend.justification = c(1, 0), 
  legend.position      = c(1, 0.1),
  legend.text          = element_text(size = 8),
  plot.margin          = unit(c(0.1, 0.1, 0.1, 0.01), "npc")   # c(bottom, left, top, right), values can be negative
)

cols    <- c( "c1" = "#ff00ff", "c2" = "#3399ff" )
shapes  <- c("s1" = 16, "s2" = 17)

p1 <- ggplot(data = arbuthnot, aes(x = year))
p1 <- p1 + geom_point(aes( y = boys,  color = "c1", shape = "s1"))
p1 <- p1 + geom_point(aes( y = girls, color = "c2", shape = "s2")) 
p1 <- p1 + labs( x = "Year", y = "Rate" )
p1 <- p1 + scale_color_manual(name = "Sex", 
                                breaks = c("c1", "c2"), 
                                values = cols,
                                labels = c("boys", "girls"))
p1 <- p1 + scale_shape_manual(name = "Sex", 
                              breaks = c("s1", "s2"),
                              values = shapes,
                              labels = c("boys", "girls"))
p1 <- p1 +  ptheme

print(p1)

выходные результаты

Ответ 3

Вот ответ, основанный на пакете tidyverse. Где можно использовать pipeу, %>%, чтобы связать функции вместе. Создание сюжета продолжается одним способом, исключая необходимость создания временных переменных. Подробнее о pipeе можно прочитать в этом посте. Что означает функция% & gt;% в R?

Насколько я знаю, легенды в ggplot2 основаны только на эстетических переменных. Таким образом, чтобы добавить дискретную легенду, используйте столбец категории и измените эстетику в соответствии с категорией. В ggplot это делается, например, aes(color=category).

Таким образом, чтобы добавить две (или более) разные переменные фрейма данных к легендам, нужно преобразовать фрейм данных таким образом, чтобы у нас был столбец категории, сообщающий нам, какой столбец (переменная) отображается, и второй столбец, который фактически содержит Значение. Функция tidyr::gather, которая также была загружена tidyverse, делает именно это.

Затем можно создать легенду, просто указав, какие переменные эстетики должны быть разными. В этом примере код будет выглядеть следующим образом:

source("http://www.openintro.org/stat/data/arbuthnot.R")
library(tidyverse)

arbuthnot %>%
    rename(Year=year,Men=boys,Women=girls) %>%
    gather(Men,Women,key = "Sex",value = "Rate") %>%
    ggplot() +
    geom_point(aes(x = Year, y=Rate, color=Sex, shape=Sex)) +
    scale_color_manual(values = c("Men" = "#3399ff","Women"= "#ff00ff")) +
    scale_shape_manual(values = c("Men" = 16, "Women" =  17))

Обратите внимание, что пакет tidyverse также автоматически загружается в пакет ggplot2. Обзор установленных пакетов можно найти на их сайте tidyverse.org.

В приведенном выше коде я также использовал функцию dplyr::rename (также загруженную tidyverse), чтобы сначала переименовать столбцы в нужные метки. Поскольку легенда автоматически принимает метки, равные названиям категорий.

Существует второй способ переименования меток легенды, который включает явное указание меток в функциях scale_aesthetic_manual с помощью аргумента labels =. Примеры смотрите в кулинарной книге легенд. Но не рекомендуется, так как это быстро запутывается с большим количеством переменных.

Ответ 4

Это трюк, который я обычно использую. Добавьте аргумент colour к aes и используйте его в качестве индикатора для имен меток.

ggplot() +
  geom_point(aes(x = year,y = boys, colour = 'Boys'),data=arbuthnot) +
  geom_point(aes(x = year,y = girls, colour = 'Girls'),data=arbuthnot,shape = 17) +
  xlab(label = 'Year') +
  ylab(label = 'Rate')

enter image description here