498

I have the following plot like below. It was created with this command:

library(ggplot2)

df <- data.frame(cond = factor(rep(c("A", "B"), each = 200)), 
                 rating = c(rnorm(200), rnorm(200, mean=.8)))

ggplot(df, aes(x=rating, fill=cond)) + 
geom_density(alpha = .3) +
xlab("NEW RATING TITLE") +
ylab("NEW DENSITY TITLE")

Now, I want to modify the legend title from cond into NEW LEGEND TITLE.

So, I just added the following line add the end of the above code:

+labs(colour="NEW LEGEND TITLE")

But it doesn't work. What's the right way to do it?

enter image description here

AndrewGB
  • 16,126
  • 5
  • 18
  • 49
neversaint
  • 60,904
  • 137
  • 310
  • 477
  • 205
    `labs(fill="xyz")` should do – baptiste Aug 23 '13 at 16:54
  • 1
    @baptiste I've come back to this question numberous times without noticing your comment, could you write it up as an answer? IMO it's the simplest solution and deserves some recognition – Preston Aug 28 '17 at 13:34
  • 4
    @User632716 it's already in someone's answer below – baptiste Aug 28 '17 at 19:45
  • 11
    it does not work... – shenglih Mar 31 '18 at 23:00
  • 7
    For those looking for an answer involving plots with multiple `geom_` statements, I recommend the answer at https://stackoverflow.com/a/38485985/1169233, it's the only one that worked for me. – Waldir Leoncio Feb 20 '20 at 13:06
  • 4
    Just note that for other types of graphs (when you use 'colour' in aes instead of 'fill') the OP question code would already work. 'Colour' is already right and not "fill"! I was going crazy trying all the answers and my solution was in the question! ;) – Juan C Apr 26 '20 at 17:09
  • 1
    Another note as of v3.3.2 -- with continuous data, change the legend title with `guides_colorbar()` to avoid the legend becoming discrete with `guides_legend()` – CzechInk Nov 18 '20 at 03:35

14 Answers14

549

This should work:

p <- ggplot(df, aes(x=rating, fill=cond)) + 
           geom_density(alpha=.3) + 
           xlab("NEW RATING TITLE") + 
           ylab("NEW DENSITY TITLE")
p <- p + guides(fill=guide_legend(title="New Legend Title"))

(or alternatively)

p + scale_fill_discrete(name = "New Legend Title")
Arun
  • 116,683
  • 26
  • 284
  • 387
  • 20
    Another alternative is `p$labels$fill <- "New Legend Title"` – Alex Holcombe Aug 31 '15 at 05:51
  • 5
    what is the difference between guides and scale_fill_discrete – Medhat Dec 29 '15 at 13:02
  • 25
    `p$labels$fill` didn't work for me. With `ggplot2_2.1.0` I use `p$labels$colour <- "New legend title"` – ClementWalter Jun 28 '16 at 13:19
  • 4
    `p$labels$fill ` is nice but if you are using more than one variable in aesthetic (linetype, color, shape) in aes, you have to change them for each separately. – discipulus Dec 09 '16 at 01:19
  • 1
    Many of the `scale_fill_...` functions can take `name` as one of the parameters. I was able to use: `scale_fill_gradientn(colors = custom_colors, na.value = "transparent", name = "New Legend Title")` in my ggplot chain. – AndrewGB Jun 19 '21 at 20:47
  • In `geom_histogram` I need `+ labs(colour = "New Legend Title", fill = "New Legend Title")` – Antoni Jun 13 '22 at 07:44
439

I didn't dig in much into this but because you used fill=cond in ggplot(),

 + labs(color='NEW LEGEND TITLE') 

might not have worked. However it you replace color by fill, it works!

+ labs(fill='NEW LEGEND TITLE') 

This worked for me in ggplot2_2.1.0

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Rohan
  • 5,121
  • 1
  • 17
  • 19
  • 39
    I think this is the most striaghtforward answer, it does exactly what OP asks for with one extra line at most – Leo Aug 14 '17 at 11:17
  • 5
    both color= and fill= should work. This is the "right" answer to the question, IMO – Dan Jan 17 '18 at 01:59
  • 4
    whether colour of fill would work depends on what "cond" (or group in other cases) is really mapped to. A good explanation could be found in http://www.cookbook-r.com/Graphs/Legends_(ggplot2)/ – user1442363 Jan 30 '18 at 12:28
  • 6
    This is the best answer. – Akshay Gaur Dec 09 '18 at 19:21
  • 7
    Note: in ggplot2 3.0+ this solution didn't work: solved it by `p + guides(fill=guide_legend(title="New Legend Title"))` – Sumax Oct 19 '19 at 06:48
  • with a grouping variable (that needs to be a factor), only `labs(color='NEW LEGEND TITLE') ` worked for me – xm1 Apr 10 '20 at 18:22
  • This also works with `labs(size='NEW LEGEND TITLE')` if you are using `geom_point(aes(size = some_size)) `. – arranjdavis Oct 07 '20 at 15:23
66

Since you have two densitys I imagine you may be wanting to set your own colours with scale_fill_manual.

If so you can do:

df <- data.frame(x=1:10,group=c(rep("a",5),rep("b",5)))

legend_title <- "OMG My Title"

ggplot(df, aes(x=x, fill=group)) + geom_density(alpha=.3) +   
    scale_fill_manual(legend_title,values=c("orange","red"))

enter image description here

user1317221_G
  • 15,087
  • 3
  • 52
  • 78
50

None of the above code worked for me.

Here's what I found and it worked.

labs(color = "sale year")

You can also give a space between the title and the display by adding \n at the end.

labs(color = 'sale year\n")

Rohit Yadav
  • 635
  • 5
  • 7
  • 5
    How is this any different than [this answer](https://stackoverflow.com/a/38938781/570918)? – merv Mar 14 '19 at 15:32
  • 5
    Yep, I tried every single example above and this is the only one that worked for me. Thanks! – SummerEla Jul 03 '19 at 17:58
  • How would this work given the original post question, it seems that `fill` instead of `color` (or `colour`) is needed? Given the time of the question, it is possible it is `ggplot2` version related. – steveb Mar 15 '20 at 22:12
  • 1
    @merv The main difference is that this one actually works. – Luís de Sousa Apr 02 '20 at 09:10
  • This is all about how you group your data and create legend based on it. If you use linetype like in ```ggplot(data=df, aes(x=time, y=value, linetype=variable))``` then ```labs(linetype = 'sale year\n")``` will work for you. – ibilgen Jun 17 '21 at 07:14
24

Since in your code you used ggplot(data, fill= cond) to create the histogram you need to add the legend title by also using "fill" in the label section i.e. +labs(fill="Title name"). If you were using a different type of plot where the code was ggplot(data, colour= cond), then you could use +labs(colour= "Title Name"). In summary, the lab argument has to match the aes argument.

I have used + guides(fill=guide_legend("my awesome title")) to change the legend title on geom_bar plots but it did not seem to work for geom_point.

kulianne
  • 249
  • 2
  • 3
  • ..., but for `geom_point()`, this works for me: `guides(color=guide_legend("Type:"))` – knb Feb 14 '18 at 15:43
  • 1
    @knb, your method works: `guides(color=guide_legend("Score Ranking:"))` – bmc Feb 23 '18 at 17:07
  • 1
    How is this any different that [this answer](https://stackoverflow.com/a/38938781/570918)? – merv Mar 14 '19 at 15:33
10

There's another very simple answer which can work for some simple graphs.

Just add a call to guide_legend() into your graph.

ggplot(...) + ... + guide_legend(title="my awesome title")

As shown in the very nice ggplot docs.

If that doesn't work, you can more precisely set your guide parameters with a call to guides:

ggplot(...) + ... + guides(fill=guide_legend("my awesome title"))

You can also vary the shape/color/size by specifying these parameters for your call to guides as well.

Yourpalal
  • 476
  • 3
  • 11
5

I am using a facet_wrap in my ggplot and none of the suggested solutions worked for me except ArnaudA's solution:

qplot(…) + guides(color=guide_legend(title="sale year")) 
Birdonawire
  • 199
  • 3
  • 10
5

Alas, none of these solutions worked for me. I am working with output from brms::conditional_effects()

My solution required:

+ labs( fill = "New Title", colour = "New Title", labels = "New Title" )
4

Just to add to the list (the other options here didn't work for me), you can also use the function update_labels for ggplot:

p <- ggplot(df, aes(x=rating, fill=cond)) + 
           geom_density(alpha=.3) + 
           xlab("NEW RATING TITLE") + 
           ylab("NEW DENSITY TITLE")
update_labels(p, list(colour="MY NEW LEGEND TITLE")

This will also allow you to change x- and y-axis labels, with separate lines:

update_labels(p, list(x="NEW X LABEL",y="NEW Y LABEL")
Eric Leung
  • 2,354
  • 12
  • 25
3

Adding this to the mix, for when you have changed the colors. This also worked for me in a qplot with two discrete variables:

p+ scale_fill_manual(values = Main_parties_color, name = "Main Parties")
Matt Ke
  • 3,599
  • 12
  • 30
  • 49
ibm
  • 744
  • 7
  • 14
3

The way i am going to tell you, will allow you to change the labels of legend, axis, title etc with a single formula and you don't need to use memorise multiple formulas. This will not affect the font style or the design of the labels/ text of titles and axis.

I am giving the complete answer of the question below.

 library(ggplot2)
 rating <- c(rnorm(200), rnorm(200, mean=.8))
 cond <-factor(rep(c("A", "B"), each = 200))
 df <- data.frame(cond,rating 
             )

 k<- ggplot(data=df, aes(x=rating, fill=cond))+ 
 geom_density(alpha = .3) +
 xlab("NEW RATING TITLE") +
 ylab("NEW DENSITY TITLE")

 # to change the cond to a different label
 k$labels$fill="New Legend Title"

 # to change the axis titles
 k$labels$y="Y Axis"
 k$labels$x="X Axis"
 k

I have stored the ggplot output in a variable "k". You can name it anything you like. Later I have used

k$labels$fill ="New Legend Title"

to change the legend. "fill" is used for those labels which shows different colours. If you have labels that shows sizes like 1 point represent 100, other point 200 etc then you can use this code like this-

k$labels$size ="Size of points"

and it will change that label title.

GAURAV JOSHI
  • 659
  • 8
  • 7
3

The only solution that works with me : p + guides(fill=guide_legend("New title")

Ayoub EL MAJJODI
  • 161
  • 1
  • 10
  • What if you wanted to keep the legend title but change the labels for each item/variable in the legend? For example, how would you change A to Alpha and B to Beta? – Angela Russell Nov 15 '21 at 01:28
  • 1
    I think if I got you question correct, legend is taken from you dataframe, so In the worst cases you can use map function with new to rename variable of you legend – Ayoub EL MAJJODI Nov 15 '21 at 08:44
  • would you mind providing a little example of how that script would look to apply the change with the map function https://stackoverflow.com/users/7739509/ayoub-el-majjodi – Angela Russell Nov 15 '21 at 08:51
  • Also worked: mutate(cond = recode(cond, "A" = "Alpha", "B" = "Beta")) %>% – Angela Russell Nov 15 '21 at 09:48
  • 1
    like this, if we want to rename legends in one column: new_names = {"A":"Alpha", "B":"Beta"} df['new_legends']= df['old_legend'].map(new_names) We will have a new column and then choose which one you can use a legend – Ayoub EL MAJJODI Nov 15 '21 at 12:26
2

I noticed there are two ways to change/specify legend.title for ggboxplot():

library(ggpubr)

bxp.defaultLegend <- ggboxplot(ToothGrowth, x = "dose", y = "len",
                               color = "dose", palette = "jco")

# Solution 1, setup legend.title directly in ggboxplot()
bxp.legend <- ggboxplot(ToothGrowth, x = "dose", y = "len",
                 color = "dose", palette = "jco", legend.title="Dose (mg)")

# Solution 2: Change legend title and appearnace in ggboxplot() using labs() and theme() option:
plot1 <-  bxp.defaultLegend + labs(color = "Dose (mg)") +
  theme(legend.title = element_text(color = "blue", size = 10), legend.text = element_text(color = "red"))

ggarrange(list(bxp.legend, bxp.defaultLegend, plot1), nrow = 1, ncol = 3,  common.legend = TRUE)

The code is modified based on the example from GitHub.

Good Will
  • 1,220
  • 16
  • 10
1

Many people spend a lot of time changing labels, legend labels, titles and the names of the axis because they don't know it is possible to load tables in R that contains spaces " ". You can however do this to save time or reduce the size of your code, by specifying the separators when you load a table that is for example delimited with tabs (or any other separator than default or a single space):

read.table(sep = '\t')

or by using the default loading parameters of the csv format:

read.csv()

This means you can directly keep the name "NEW LEGEND TITLE" as a column name (header) in your original data file to avoid specifying a new legend title in every plot.

Nakx
  • 1,460
  • 1
  • 23
  • 32