Home > Software design >  How to add labels and points to each geom_line in ggplot2?
How to add labels and points to each geom_line in ggplot2?

Time:09-22

I have a dataframe called (casos_obitos) that looks something like this:

EPI_WEEK    CASES       DEATHS
 SE 51      1053          19
 SE 52      1384          21
 SE 53      1892          25
SE 01/21     1806          43

I'm making a plot with ggplot that places both cases and deaths in two different geom_lines. This is my code:

   scl = 10

ggplot(data = casos_obitos, aes(x = EPI_WEEK, y = CASES, fill = CASES, group =1)) 
      scale_y_continuous(limits = c(0, max(casos_obitos$CASES) 10), expand = expansion(mult = c(0, .1)),
                         sec.axis = sec_axis(~./scl, name = "Nº de Óbitos")) 
      geom_line(aes(x = SEM_EPI, y = CASES, color = "CASES"), size = 1) 
      geom_line(aes(x = SEM_EPI, y = DEATHS*scl, color = "DEATHS"), size = 1)  
      geom_text(aes(label= CASES), hjust= 0.5, vjust = -2, size= 2.0, color= "black")  
      labs(x = "Semana Epidemiológica", y = "Nº de Casos")  
      scale_colour_manual(" ", values=c("CASES" = "blue", "DEATHS" = "red")) 
      theme_minimal(base_size = 10)  
      theme(legend.position = "bottom", axis.line = element_line(colour = "black"), 
            axis.text.x=element_text(angle = 90, vjust = 0.5, hjust=1, color="black"), 
            axis.text.y=element_text(color="black"))

For now, my plot looks like this:

enter image description here

Where the blue line is the cases column and the red one is the deaths column. I need to put labels on the red line but I can't seem to find answers for that. I also wany to put labels in a "nice looking" way so I can understand the numbers and they don't look messy like they're right now.

Thanks!

CodePudding user response:

You should be able to add the following to get labels on the bottom line:

geom_text(aes(y = DEATHS*scl, label= DEATHS), hjust= 0.5, vjust = -2, size= 2.0, color= "black")  

You might also consider reshaping your data into a long format so that the CASES and DEATHS (after scaling) values are combined into the same column, with another column distinguishing which series is related to each value. ggplot2 generally works more smoothly with data in that form -- you would map the color aesthetic to the column specifying which series, and then you'd only need one geom_line and one geom_text to get both series. In this case, with only two series, and one of them scaled, it might not be worth the trouble to switch.

"Nice looking labels" is subjective and a harder problem than it might sound. There are a few options, including:

  1. use a function like ggrepel::geom_text_repel to automatically shift labels from overlapping each other. It works by starting from an initial point and iteratively nudging until the labels have as much separation as you've specified. Many options for adjusting the initial starting position and how the nudging should work.

  2. manually nudge the labels you need to using code, e.g. by adjusting vjust for certain points. You might, for instance, use vjust to make the labels under the line for the points that are lower than neighboring points, by pre-calculating a moving average and comparing values to that.

  3. manually nudge the points afterward, e.g. by using officer/svg to output to a vector file you can edit in powerpoint, for instance.

  4. avoid persistent labels altogether by shifting to an interactive option like ggplotly and see the labels upon hover instead of all the time.

You might also take a look at functions like scales::comma to control how the labels themselves appear. I'm anticipating that your Deaths labels will have many digits of decimals but you probably just will want the integer part of that...

  • Related