How to Combine Scales for Colour and Size into One Legend

How to combine scales for colour and size into one legend?

Use the guides() function of ggplot2. In this case:

ggplot(df,aes(V1,V2))+
geom_point(aes(colour=V3,size=V3))+
scale_colour_gradient(low="grey", high="black")+
scale_size(range=c(1,10)) +
guides(color=guide_legend(), size = guide_legend())

ggplot2 will try to integrate the scales for you. It doesn't in this case because the default guide for a color scale is a colorbar and the default guide for size is a normal legend. Once you set them both to be legends, ggplot 2 takes over and combines them.

Sample Image

R ggplot combine legends for colour and fill with different factor length

By default the scale drops unused factor levels, which is relevant here because can only get lines for a couple of your groups.

You can use drop = FALSE to change this in the appropriate scale_*_manual() (which is for fill here).

Then use the same vector of colors for both the fill and color scales. I usually make a named vector for this.

# Make vector of colors
colors = c("25" = 'grey20', "30" = 'blue', "35" = 'grey20', "40" = 'tomato3', "45" = 'grey20')

#Plot
ggplot(data = Data, aes(x = Man1, y = DV, group=as.factor(Man2), colour= as.factor(Man2))) +
theme_bw() +
geom_abline(intercept = 0, slope = 1, linetype = "longdash") +
geom_point(position = position_dodge(1)) +
geom_smooth(method = "lm", aes(fill=as.factor(Man2))) +
scale_colour_manual(name = "Man2", values = colors) +
scale_fill_manual(name = "Man2", values = colors, drop = FALSE)

Sample Image
Alternatively, use guide = "none" to remove the fill legend all together.

ggplot(data = Data, aes(x = Man1, y = DV, group=as.factor(Man2), colour= as.factor(Man2))) +
theme_bw() +
geom_abline(intercept = 0, slope = 1, linetype = "longdash") +
geom_point(position = position_dodge(1)) +
geom_smooth(method = "lm", aes(fill=as.factor(Man2))) +
scale_colour_manual(name = "Man2", values = colors) +
scale_fill_manual(name = "Man2", values=c('blue','tomato3'), guide = "none")

Sample Image

Combine legends for color and shape into a single legend

You need to use identical name and labels values for both shape and colour scale.

pd <- position_dodge(.65)
ggplot(data = data,aes(x= year, y = beta, colour = group2, shape = group2)) +
geom_point(position = pd, size = 4) +
geom_errorbar(aes(ymin = lcl, ymax = ucl), colour = "black", width = 0.5, position = pd) +
scale_colour_manual(name = "Treatment & State",
labels = c("Control, Non-F", "Control, Flwr", "Exclosure, Non-F", "Exclosure, Flwr"),
values = c("blue", "red", "blue", "red")) +
scale_shape_manual(name = "Treatment & State",
labels = c("Control, Non-F", "Control, Flwr", "Exclosure, Non-F", "Exclosure, Flwr"),
values = c(19, 19, 17, 17))

Sample Image

Merge separate size and fill legends in ggplot

Looking at this answer citing R-Cookbook:

If you use both colour and shape, they both need to be given scale specifications. Otherwise there will be two two separate legends.

Thus we can infer that it is the same with size and fill arguments. We need both scales to fit. In order to do that we could add the breaks=pretty_breaks(4) again in the scale_fill_distiller() part. Then by using guides() we can achieve what we want.

set.seed(42)  # for sake of reproducibility
lat <- rnorm(10, 54, 12)
long <- rnorm(10, 44, 12)
val <- rnorm(10, 10, 3)

df <- as.data.frame(cbind(long, lat, val))

library(ggplot2)
library(scales)
ggplot() +
geom_point(data=df,
aes(x=lat, y=long, size=val, fill=val),
shape=21, alpha=0.6) +
scale_size_continuous(range = c(2, 12), breaks=pretty_breaks(4)) +
scale_fill_distiller(direction = -1, palette="RdYlBu", breaks=pretty_breaks(4)) +
guides(fill = guide_legend(), size = guide_legend()) +
theme_minimal()

Produces:
Sample Image

ggplot: combining size and color in legend

ggplot2 can indeed combine size and colour legends into one, however, this only works, if they are compatible: they need to have exactly the same breaks, otherwise they can not be combined.

Let me make an example: Assume, you have values between 0 and 10 that you want to map on size and colour. You tell ggplo2 to use small points for values below 5 and large points for larger value. It will then plot a legend with a small and a large point, as expected. Now, you also want to add colour and you require points below 3 to be green and points above to be blue. ggplot2 will also draw a legend for this, but it is impossible to combine the two legends. The small point would have to be both, green and blue. The problem can be solved by using the same breaks for colour and size.

In your example, you manually change the breaks of the colour scale, but not those of the size scale. This results in incompatible legends that can not be combined.

I can not demonstrate this using your date, because I don't have it. So I will create an example with mtcars. The variant with incompatible legends is constructed as follows:

p <- ggplot(mtcars, aes(x=mpg, y=drat)) +
geom_point(aes(size=gear, color=gear)) +
scale_color_continuous(limits=c(2, 5), breaks=seq(2, 5, by=0.5)) +
guides(color= guide_legend(), size=guide_legend())

which gives the following plot:

Sample Image

If I now add the same breaks for size,

p + scale_size_continuous(limits=c(2, 5), breaks=seq(2, 5, by=0.5))

I get a plot with only one legend:

Sample Image

For your code, this means that you should add the following to your plot:

+ scale_size_continuous(limits=c(0, 30000), breaks=seq(0,30000, by=2500))

A little side remark: What do you intend by using colour = "green" in your call to ggplot? I don't see that this has any effect at all, because you set the colour again in both geoms that you use later. Maybe a relic from an older variant of the plot?

Combine/Merge color and fill legend into one

You can pass dummy fill variable for geom_line (by default they don't have it, but we will use one fill legend). Next you have to set all three values in fill and remove color legend.

ggplot(df, aes(x = Date)) + 
geom_area(aes(y = B / 1000000, fill = "B")) +
geom_line(aes(y = (A_pct * m) + b, color = "A % Chg", fill = "A % Chg"), size = 1.5) +
geom_line(aes(y = (B_pct * m) + b, color = "B % Chg", fill = "B % Chg"), size = 1.5) +
scale_color_manual(values = c("red", "blue"), guide = FALSE) +
scale_fill_manual(values = c("red", "yellow", "blue"),
name = "Series")

Sample Image

How to merge legends with multiple scale_identity (ggplot2)?

I think scale_color_manual is the way to go here because of its versatility. Your concerns about repetition and maintainability are justified, but the solution is to keep a separate data frame of aesthetic mappings:

library(tidyverse)

df <- data.frame(name = c('a','a','b','b','c','c'),
x = c(1,5,1,3,3,4),
y = c(1,3,2,1,3,2))

scale_map <- data.frame(name = c("a", "b", "c"),
color = c("blue", "red", "blue"),
shape = c(16, 16, 17))

df %>%
ggplot(aes(x = x, y = y, color = name, shape = name)) +
geom_line() +
geom_point(size = 3) +
scale_color_manual(values = scale_map$color, labels = scale_map$name,
name = "name") +
scale_shape_manual(values = scale_map$shape, labels = scale_map$name,
name = "name")

Sample Image

Created on 2022-04-15 by the reprex package (v2.0.1)

How can I combine legends for color and linetype into a single legend in ggplot?

Try this. Make a hash of the two fields you're using (mutate(hybrid = paste(Meteorological_Season_Factor, Treatment))), and then use that for both color and line type (aes(...col = hybrid, linetype = hybrid)), and then use named vectors for your values in both scale functions.

Is that what you're looking for? (P.S. I believe I used the labels and values you used in the order in which you used them... maybe that was the only problem is that you'd transposed a couple of them!)

SOtestplot <- test %>%
mutate(hybrid = paste(Meteorological_Season_Factor, Treatment)) %>%
filter(Species == "MEK", binned_alt <= 8000) %>%
ggplot(aes(y = binned_alt/1000, x = `50%`, col = hybrid, linetype = hybrid)) +
geom_path(size = 1.2) +
theme_tufte(base_size = 22) +
geom_errorbarh(aes(xmin =`25%`, xmax = `75%`), height = 0) +
theme(axis.title.x = element_text(vjust=-0.5),
axis.title.y = element_text(vjust=1.5),
panel.grid.major = element_line(colour = "grey80"),
axis.line = element_line(size = 0.5, colour = "black")) +
scale_color_manual(name = "Treatment & Season",
values = c(
`Summer Clean Marine` = "cornflowerblue",
`Winter Clean Marine` = "goldenrod3",
`Summer All Data` = "cornflowerblue",
`Winter All Data` = "goldenrod3"
)) +
scale_linetype_manual(name = "Treatment & Season",
values = c(
`Summer Clean Marine` = "solid",
`Winter Clean Marine` = "dashed",
`Summer All Data` = "solid",
`Winter All Data` = "dashed")
) +
xlab("MEK (ppt)") +
ylab("Altitude (km)")

Combine aes and manual scales to create legend in ggplot (two data frames)

like this?

You can feed your geom_line and geom_point aesthetics a colour to map to. Then use scale_colour_manual to adjust the colour and name.

dd <- data.frame(Year = rep(2005:2021, 2),
Balance = c(rep("Output", 17), rep("Input", 17)),
Total = c(runif(17, min = 100, max = 200),
runif(17, min = -99, max = -10)))
drs <- filter(dd, Year %in% c(2005, 2010, 2015, 2020)) %>%
arrange(Year, Balance) %>%
group_by(Year) %>%
mutate(diff = cumsum(Total)) %>%
ungroup()

ggplot() +
geom_bar(data = dd,
stat = "identity", aes(x = Year, y = Total, fill = Balance)) +
geom_line(data = filter(drs, Balance == "Output"),
aes(x = Year, y = diff, colour = Balance), size = 1) +
geom_point(data = filter(drs, Balance == "Output"),
aes(x = Year, y = diff, colour = Balance), size = 2) +
scale_fill_brewer(name = "", palette = "Blues") +
scale_colour_manual(values = c("black"), name = "Balance2") + #Here is where I have issues
theme_bw() +
theme(text = element_text(size = 21))



Related Topics



Leave a reply



Submit