Two geom_points add a legend

前端 未结 4 1723
悲哀的现实
悲哀的现实 2020-11-29 06:45

I plot a 2 geom_point graph with the following code:

source(\"http://www.openintro.org/stat/data/arbuthnot.R\")
library(ggplot2)
ggplot() +
  geom_point(aes(         


        
相关标签:
4条回答
  • 2020-11-29 07:08

    If you rename your columns of the original data frame and then melt it into long format withreshape2::melt, it's much easier to handle in ggplot2. By specifying the color and shape aesthetics in the ggplot command, and specifying the scales for the colors and shapes manually, the legend will appear.

    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

    0 讨论(0)
  • 2020-11-29 07:22

    This is the trick that I usually use. Add colour argument to the aes and use it as an indicator for the label names.

    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')
    

    0 讨论(0)
  • 2020-11-29 07:32

    Here is an answer based on the tidyverse package. Where one can use the pipe, %>%, to chain functions together. Creating the plot in one continues manner, omitting the need to create temporarily variables. More on the pipe can be found in this post What does %>% function mean in R?

    As far as I know, legends in ggplot2 are only based on aesthetic variables. So to add a discrete legend one uses a category column, and change the aesthetics according to the category. In ggplot this is for example done by aes(color=category).

    So to add two (or more) different variables of a data frame to the legends, one needs to transform the data frame such that we have a category column telling us which column (variable) is being plotted, and a second column that actually holds the value. The tidyr::gather function, that was also loaded by tidyverse, does exactly that.

    Then one creates the legend by just specifying which aesthetics variables need to be different. In this example the code would look as follows:

    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))
    

    Notice that tidyverse package also automatically loads in the ggplot2 package. An overview of the packages installed can be found on their website tidyverse.org.

    In the code above I also used the function dplyr::rename (also loaded by tidyverse) to first rename the columns to the wanted labels. Since the legend automatically takes the labels equal to the category names.

    There is a second way to renaming labels of legend, which involves specifying the labels explicitly in the scale_aesthetic_manual functions by the labels = argument. For examples see legends cookbook. But is not recommended since it gets messy quickly with more variables.

    0 讨论(0)
  • 2020-11-29 07:33

    Here is a way of doing this without using reshape::melt. reshape::melt works, but you can get into a bind if you want to add other things to the graph, such as line segments. The code below uses the original organization of data. The key to modifying the legend is to make sure the arguments to scale_color_manual(...) and scale_shape_manual(...) are identical otherwise you will get two legends.

    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)
    

    output results

    0 讨论(0)
提交回复
热议问题