1

I am trying to change the legend of my ggplot graph but I don't manage to do so. This is my df and my code for the graph:

#df
df = structure(list(Date = structure(c(18319, 18320, 18321, 18322, 
18323, 18324, 18325, 18326, 18327, 18328, 18329, 18330, 18331, 
18332, 18333, 18334, 18335, 18336, 18337, 18338, 18339, 18340, 
18341, 18342, 18343), class = "Date"), Daily_Cases = c(250, 238, 
240, 566, 342, 466, 587, 769, 778, 1247, 1492, 1797, 977, 2313, 
2651, 2547, 3497, 3590, 3233, 3526, 4207, 5322, 5986, 6557, 5560
), Tests = c(2427, 3681, 2966, 2466, 2218, 2511, 3981, 2525, 
3997, 5703, 7875, 3889, 6935, 12393, 12857, 11477, 11682, 15729, 
13063, 10695, 16884, 17236, 24109, 26336, 25180), Proportion = c(10.3, 
6.5, 8.1, 23, 15.4, 18.6, 14.7, 30.5, 19.5, 21.9, 18.9, 46.2, 
14.1, 18.7, 20.6, 22.2, 29.9, 22.8, 24.7, 33, 24.9, 30.9, 24.8, 
24.9, 22.1)), class = "data.frame", row.names = c(NA, -25L))


df <- df %>% pivot_longer(names_to = 'Legend', values_to = 'value', Tests:Daily_Cases) 

ggplot(df) + theme_bw() +
  geom_col(aes(Date, value, fill = Legend), position = position_dodge()) +
  geom_line(aes(Date, Proportion*1000, colour = "Infected (%)", group = 1), size = 0.8) + scale_y_continuous("\n", sec.axis = sec_axis(~ . /1000, name = "(%) \n")) + labs(x="", y="") + 
  scale_colour_manual(" ", values=c("Infected (%)" = "black")) +
  theme(legend.position = "bottom")

This is the result:

enter image description here

However, I want to be able to remove the word Legend and also change the words Daily_Cases and Tests into Number of Cases and Number of Tests respectively.

I don't manage to do so. Can anyone help me?

Rollo99
  • 1,601
  • 7
  • 15
  • 1
    Does this answer your question? [How to change legend title in ggplot](https://stackoverflow.com/questions/14622421/how-to-change-legend-title-in-ggplot) – tjebo Mar 23 '20 at 16:33
  • 1
    for changing the labels see https://stackoverflow.com/questions/23635662/editing-legend-text-labels-in-ggplot - here in particular you can do all with `scale_fill_manual` – tjebo Mar 23 '20 at 16:36
  • @Tjebo Gosh googling for 20 min and didn't find these! – Rollo99 Mar 23 '20 at 16:42
  • 1
    Don't worry. One thing that comes with more experience is knowing how to google for certain questions. – tjebo Mar 23 '20 at 16:43
  • 1
    @Tjebo I'm struggling to decide which one. They are all great and they would all deserve full points answer. I'll mark it shortly – Rollo99 Mar 23 '20 at 16:48
  • 1
    @Tjebo This is what I went for: lowest score. But all the answers were great and super fast! Thank you all for sorting this out! – Rollo99 Mar 23 '20 at 16:54

3 Answers3

4

One approach is scale_fill_discrete.

ggplot(df) + theme_bw() +
  geom_col(aes(Date, value, fill = Legend), position = position_dodge()) + 
  scale_fill_discrete(name=NULL,labels=c("Number of Cases","Number of Tests")) +
  geom_line(aes(Date, Proportion*1000, colour = "Infected (%)", group = 1), size = 0.8) + scale_y_continuous("\n", sec.axis = sec_axis(~ . /1000, name = "(%) \n")) + labs(x="", y="") + 
  scale_colour_manual(" ", values=c("Infected (%)" = "black")) +
  theme(legend.position = "bottom")
Ian Campbell
  • 23,484
  • 14
  • 36
  • 57
4

All the answers to your questions are modifications applied to your code based on the answer here to a related question on working with Legends in ggplot. The simplest method is to add a call to scale_fill_manual() similar to what you already did with scale_color_manual():

ggplot(df) + theme_bw() +
    geom_col(aes(Date, value, fill = Legend), position = position_dodge()) +
    geom_line(aes(Date, Proportion*1000, colour = "Infected (%)", group = 1), size = 0.8) + 
    scale_y_continuous("\n", sec.axis = sec_axis(~ . /1000, name = "(%) \n")) + labs(x="", y="") + 
    scale_colour_manual(" ", values=c("Infected (%)" = "black")) +
    theme(legend.position = "bottom") +
    scale_fill_manual("", values=c('Daily_Cases'='blue', 'Tests'='red'), labels=c('Numer of Cases', 'Number of Tests'))

Giving you below (you can change the colors to whatever you want, but I think this is what you were looking for):

enter image description here

As the other user pointed out, you can use scale_fill_discrete() to just keep the default colors and only specify labels:

ggplot(df) + theme_bw() +
    geom_col(aes(Date, value, fill = Legend), position = position_dodge()) +
    geom_line(aes(Date, Proportion*1000, colour = "Infected (%)", group = 1), size = 0.8) +
    scale_y_continuous("\n", sec.axis = sec_axis(~ . /1000, name = "(%) \n")) + labs(x="", y="") + 
    scale_colour_manual(" ", values=c("Infected (%)" = "black")) +
    theme(legend.position = "bottom") +
    scale_fill_discrete("", labels=c('Numer of Cases', 'Number of Tests'))
chemdork123
  • 12,369
  • 2
  • 16
  • 32
3

All correct answers, but I'd simply use a named vector in scale_fill_ etc

This is not only a matter of convenience, but also safer, as you have better control about your labelling.

Also, don't use name = '', because "something" will be drawn. Use NULLinstead

ggplot(df) + theme_bw() +
  geom_col(aes(Date, value, fill = Legend), position = position_dodge()) +
  geom_line(aes(Date, Proportion*1000, colour = "Infected (%)", group = 1), size = 0.8) + scale_y_continuous("\n", sec.axis = sec_axis(~ . /1000, name = "(%) \n")) + labs(x="", y="") + 
  scale_colour_manual(" ", values=c("Infected (%)" = "black")) +
  theme(legend.position = "bottom") +
scale_fill_brewer(name = NULL, labels = c(Daily_Cases = 'Number of cases', Tests = 'Number of Tests'))
tjebo
  • 21,977
  • 7
  • 58
  • 94