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:
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:
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.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.
manually nudge the points afterward, e.g. by using
officer
/svg
to output to a vector file you can edit in powerpoint, for instance.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...