Display ggplot legend correctly for line/shape combinations - r

I am trying to create a plot for three groups using three different coloured lines but only two of the groups have point markers. I can get the plot to display correctly but the legend shows the same point markers for all three groups.
I have created a reproducible example using the mpg dataset
library(tidyverse)
ggplot(mpg) +
geom_line(mapping = aes(x = displ, y = cty, color = drv), size = 1) +
geom_point(data = subset(mpg, drv != '4'), mapping = aes(x = displ, y = cty, color = drv, shape = drv), size = 3) +
scale_color_manual(name="Variable", labels = c("4", "f", "r"), values=c("4" = "#DA2128", "f" = "black", "r" = "blue")) +
scale_shape_manual(name="Variable", labels = c("f", "r"), values = c("f" = 16, "r" = 17), guide = FALSE)
The group '4' should have no point marker in the legend and the group 'r' should show a triangle marker
Thanks in advance for your help

Try some alpha
ggplot(mpg, aes(x = displ, y = cty, color = drv, shape = drv)) +
geom_line() +
geom_point(aes(alpha=drv), size = 3) +
scale_alpha_manual(values = c(0,1,1)) +
scale_shape_manual(values = c(1,16, 17))
Or simply set shape 4 to NA
ggplot(mpg, aes(x = displ, y = cty, color = drv, shape = drv)) +
geom_line() +
geom_point(size = 3) +
scale_shape_manual(values = c(NA, 16, 17)) +
scale_color_manual(values = c("#DA2128", "black", "blue"))

Adding linetype argument in your geom_line() with the variable of interest (drv in this case) gives your expected result.
library(tidyverse)
ggplot(mpg) +
geom_line(mapping = aes(x = displ, y = cty, color = drv, linetype = drv), size = 1) +
geom_point(data = subset(mpg, drv != '4'), mapping = aes(x = displ, y = cty, color = drv, shape = drv), size = 3) +
scale_color_manual(name="Variable", labels = c("4", "f", "r"), values=c("4" = "#DA2128", "f" = "black", "r" = "blue")) +
scale_shape_manual(name="Variable", labels = c("f", "r"), values = c("f" = 16, "r" = 17), guide = FALSE)

You could also disable the legend for shape and set the values for shape manually in the color legend:
ggplot(mpg) +
geom_line(mapping = aes(x = displ, y = cty, color = drv), size = 1) +
geom_point(data = subset(mpg, drv != '4'), mapping = aes(x = displ, y = cty, color = drv, shape = drv), size = 3) +
scale_color_manual(name="Variable", labels = c("4", "f", "r"), values=c("4" = "#DA2128", "f" = "black", "r" = "blue"), guide=guide_legend(override.aes = list(shape = c("4" = NA, "f" = 16, "r" = 17)))) +
scale_shape_manual(values = c("f" = 16, "r" = 17), guide=F)

Related

How to solve the conflict between fill and facet_grid in R when inserting text in a ggplot?

I can straightforwardly insert text in a faceted ggplot using the following code
mpg_plot <- ggplot(mpg, aes(x = displ, y = hwy)) +
geom_point() +
facet_grid(. ~ drv)
f_labels <- data.frame(drv = c("4", "f", "r"), label = c("4wd", "Front", "Rear"))
mpg_plot +
geom_text(x = 6, y = 40, aes(label = label), data = f_labels)
However, I get an "Error in FUN(X[[i]], ...) : object 'cyl' not found" if I try to provide colors like in the following example.
mpg$cyl = as.factor(mpg$cyl)
ggplot(mpg, aes(x = displ, y = hwy, fill=cyl)) +
geom_point(aes(col=cyl)) +
scale_fill_manual(values = c("red","blue","green","yellow")) +
facet_grid(. ~ drv) +
geom_text(x = 6, y = 40, aes(label = label), data = f_labels)
mpg_plot
In that scenario, the resulting plot has neither color, nor the annotation. Is there a way to make fill compatible with facet_grid?
The issue is that your dataset f_labels has no column cyl which you specified as a global aes via fill=cyl. Simply removing it will fix your issue. Also, as the default shape for points has no fill aes you have to switch to scale_color_manual to color your points:
library(ggplot2)
f_labels <- data.frame(drv = c("4", "f", "r"), label = c("4wd", "Front", "Rear"))
mpg_plot +
geom_text(x = 6, y = 40, aes(label = label), data = f_labels)
#> Error in eval(expr, envir, enclos): object 'mpg_plot' not found
mpg$cyl <- as.factor(mpg$cyl)
ggplot(mpg, aes(x = displ, y = hwy)) +
geom_point(aes(col = cyl)) +
scale_color_manual(values = c("red", "blue", "green", "yellow")) +
facet_grid(. ~ drv) +
geom_text(x = 6, y = 40, aes(label = label), data = f_labels)

How to insert annotation on the very top facet of ggplot in R?

I would like to have the annotation on the very first facet of the following ggplot. right now, the code draws annotation on all facets. Anyway forward would be appreciate.
library(ggplot2)
library(lubridate)
set.seed(123)
DF <- data.frame(Date = seq(as.Date("2001-01-01"), to = as.Date("2005-12-31"), by = "1 month"),
Ob = runif(60,1,5), L95 =runif(60, 0,4), U95 = runif(60,2,7), Sim = runif(60,1,5)) %>%
pivot_longer(names_to = "Variable", values_to = "Value", -Date)
ggplot(data = DF, aes(x = Date))+
geom_line(aes(y = Value))+
facet_wrap(~ Variable, scales = "free_y", nrow = 4)+
geom_vline(xintercept = as.Date("2004-12-01"),color = "red", size = 1.30)+
annotate(geom = "text", x = as.Date("2002-01-01"), y = 3, label = "Calibration")+
annotate(geom = "text", x = as.Date("2005-06-01"), y = 3, label = "Validation")
You can do this with geom_text. Create a separate dataframe for plotting.
library(ggplot2)
text_data <- data.frame(x = as.Date(c("2002-01-01", "2005-06-01")),
y = 3.5, Variable = sort(unique(DF$Variable))[1],
label = c("Calibration", "Validation"))
ggplot(data = DF, aes(x = Date))+
geom_line(aes(y = Value))+
facet_wrap(~ Variable, scales = "free_y", nrow = 4)+
geom_vline(xintercept = as.Date("2004-12-01"),color = "red", size = 1.30) +
geom_text(data = text_data, aes(x, y, label = label), color = 'blue')
You can try something like this wrapping data coordinates for the value on top of facets using geom_text():
library(ggplot2)
library(lubridate)
#Code
ggplot(data = DF, aes(x = Date))+
geom_line(aes(y = Value,group=Variable))+
facet_wrap(~ Variable, scales = "free_y", nrow = 4)+
geom_vline(xintercept = as.Date("2004-12-01"),color = "red", size = 1.30)+
geom_text(data=data.frame(Variable='L95',Date=as.Date("2002-01-01"),
label="Calibration",Value=max(DF$Value)),
aes(y=Value,label=label))+
geom_text(data=data.frame(Variable='L95',Date=as.Date("2005-06-01"),
label="Validation",Value=max(DF$Value)),
aes(y=Value,label=label))
Output:

Defining Legends using ggplot

I am trying to define the legends of my plot in R.
I have the following code, this is a demo only, real data will have 7-8 columns and up to 20 samples
library(ggplot2)
library(RColorBrewer)
colors <-brewer.pal(n = 3, name = 'Paired')
ids <- c("TestA", "TestB", "TestC")
bg <-c(23, 13, 15)
sample1 <- c(21,15,17)
sample2 <- c(27,25,11)
sample3 <- c(24,14,18)
df <- data.frame(ids, bg, sample1,sample2,sample3)
ggplot(df) +
geom_col(aes(x = ids, y = bg), size = 1, color = "grey", fill = "grey") +
geom_point(aes(x = ids, y = sample1), size = 10, color=colors[1], group = 1) +
geom_point(aes(x = ids, y = sample2), size = 10, color=colors[2], group = 1) +
geom_point(aes(x = ids, y = sample3), size = 10, color=colors[3], group = 1)+
ggtitle("Plot title") +
xlab("x label") + ylab(" y label") +
scale_colour_manual(values = c("95% PI"= "black",
"Forecasts" = "red",
"Threshold" = "green"))
It produces the following output
How can I add legends like the following picture, and ensure that the color matches, i.e. legend color matches sample or bg color
Is this something like what you want?
ggplot(df) +
geom_col(aes(x = ids, y = bg, fill = "background"), size = 1, color = "grey") +
geom_point(data = df %>% pivot_longer(cols = starts_with("sample"), names_to = "sample", values_to = "values"), aes(x = ids, y = values, color = sample), size = 10) +
ggtitle("Plot title") +
xlab("x label") + ylab(" y label") +
scale_colour_manual(name = NULL, values = c("sample1"= "black",
"sample2" = "red",
"sample3" = "green"),
labels = c("95% PI", "forecasts", "Threshold")) +
scale_fill_manual(name = NULL, values = c("background" = "grey"))

Legend for additional points in a ggplot

Steeling the example of this question (Link), I want to ask if it is possible to add the additional blue point to the legend?
dat <- data.frame(cond = rep(c("A", "B"), each=10),
xvar = 1:20 + rnorm(20,sd=3),
yvar = 1:20 + rnorm(20,sd=3))
g1 <- dat[15,]
ggplot(dat, aes(x = xvar, y = yvar, shape = cond,
colour = cond), size = 2.5) +
geom_point(alpha = 1) +
geom_point(data = g1, colour = "blue", size = 4, show_guide = FALSE)
You can put the aesthetics for the additional points layer inside aes instead of outside to get it added to the legend. You can use any string value; that string will be the name in the legend.
Then you can control the color and shape of that point via scale_*_manual layers.
I additionally changed the size of that point in the legend using override.aes, which is optional.
ggplot(dat, aes(x = xvar, y = yvar, shape = cond,
colour = cond), size = 2.5) +
geom_point(alpha = 1) +
geom_point(data = g1, aes(colour = "Point 15", shape = "Point 15"), size = 4) +
scale_shape_manual(values = c(16, 17, 17) ) +
scale_color_manual(values = c("pink", "turquoise", "blue") ) +
guides(color = guide_legend( override.aes = list(size = c(1.5, 1.5, 4) ) ) )
You probably have to change the condition of that point in the data as in your example or add it to the date, if it is not already part of it.
dat <- data.frame(cond = rep(c("A", "B"), each=10),
xvar = 1:20 + rnorm(20,sd=3),
yvar = 1:20 + rnorm(20,sd=3))
dat$size = 2.5
dat[15,]$cond = "C"
dat$cond = as.character(dat$cond)
dat[15,]$size = 4
ggplot(dat, aes(x = xvar, y = yvar, shape = cond,
colour = cond, size=size)) +
geom_point(alpha = 1) +
scale_colour_manual(values=c("red", "turquoise", "blue")) +
scale_size_continuous(guide = FALSE)

Plot standardized sizes with or without legends (ggplot, grid.arrange)

I have a serie of plots (more than 10) arranged on 2 colonnes using grid.arrange. Since they all possess the same x axis labels, I am ploting the x axis labels only for the last array. However, the plots part of the last array are compressed and reduced in size
Here is a reproducible example of the problem:
source("http://www.openintro.org/stat/data/arbuthnot.R")
library(ggplot2)
library(reshape2)
library(gridExtra)
names(arbuthnot) <- c("Year", "Men", "Women")
arbuthnot.melt <- melt(arbuthnot, id.vars = 'Year', variable.name = 'Sex',
value.name = 'Rate')
p1 <- ggplot(arbuthnot.melt, aes(x = Year, y = Rate, shape = Sex, color = Sex, linetype = Sex))+
geom_line() + scale_color_manual(values = c("Women" = '#ff00ff','Men' = '#3399ff')) +
scale_linetype_manual(values = c('Women' = 'solid', 'Men' = 'dotted')) +
theme (axis.text.x=element_blank(),axis.title.x=element_blank())
p2 <- ggplot(arbuthnot.melt, aes(x = Year, y = Rate, shape = Sex, color = Sex, linetype = Sex))+
geom_line() + scale_color_manual(values = c("Women" = '#ff00ff','Men' = '#3399ff')) +
scale_linetype_manual(values = c('Women' = 'solid', 'Men' = 'dotted')) +
theme (axis.text.x=element_blank(),axis.title.x=element_blank())
p3 <- ggplot(arbuthnot.melt, aes(x = Year, y = Rate, shape = Sex, color = Sex, linetype = Sex))+
geom_line() + scale_color_manual(values = c("Women" = '#ff00ff','Men' = '#3399ff')) +
scale_linetype_manual(values = c('Women' = 'solid', 'Men' = 'dotted')) +
scale_x_continuous(expand = c(0, 0), labels=c("FSSFDFSDSDF", "ASD","QDDZXCC","QDDZXCC","QDDZXCC")) +
theme(axis.text.x = element_text(hjust = 1, angle=90))
p4 <- ggplot(arbuthnot.melt, aes(x = Year, y = Rate, shape = Sex, color = Sex, linetype = Sex))+
geom_line() + scale_color_manual(values = c("Women" = '#ff00ff','Men' = '#3399ff')) +
scale_linetype_manual(values = c('Women' = 'solid', 'Men' = 'dotted')) +
scale_x_continuous(expand = c(0, 0), labels=c("FSSFDFSDSDF", "ASD","QDDZXCC","QDDZXCC","QDDZXCC")) +
theme(axis.text.x = element_text(hjust = 1, angle=90))
grid.arrange(p1, p2, p3, p4, ncol=2)
Is it possible to standardize the plot formats with no regards to the fact that they possess or not a legend? Im my case, it is even impossible to read the content of the last two plots...

Resources