How to avoid repeated text due to strip in R? - r

I want to add a text to my forest plot in R that has strip in it but the text is repeated on every strip . how can I add only the text to one strip or just on the plot? My code is as below:
My data is like:
Group Mean LowerLimit UpperLimit
M 1.172827 1.083498 1.268857
H 5.142589 4.333141 6.148088
h<-"XXXX"
p = ggplot(data=df4,
aes(x = Group,y = Mean, ymin = LowerLimit, ymax = UpperLimit),
+
ggtitle(PlotTitle)+
geom_point(aes(fill=Group, color=Group), shape=22, size=3)+
geom_pointrange(aes(col=Group), fatten = 3)+
geom_hline(aes(),yintercept =1, linetype="longdash")+
geom_text(aes(-1.5, 0.8, vjust =-0.5, hjust=-0.8, size=10),label=h,
check_overlap = T)+
geom_errorbar(aes(ymin=LowerLimit,
ymax=UpperLimit,col=Group),width=0.4,cex=1)+
facet_wrap(~Group,strip.position="left",nrow=2, scales= "free_y") +
theme(plot.title=element_text(aes(5, 5), hjust=0.5, size=14,face="bold"),
legend.position='none',
strip.text.y = element_text(size=10, hjust=0.5,vjust =1,lineheight=0.1, angle=270,face="bold"),
panel.background = element_blank(),
strip.background = element_rect(fill="green"),
plot.margin = margin(3.5,0.1,3.5, 0.5, "cm"))+
coord_flip()
p

In your parameters for geom_text try changing label=h to label = ''
library(ggplot2)
df4 <- data.frame(Group = c("M", "H"),
Mean = c(1.172827, 5.142589),
LowerLimit = c(1.083498, 4.333141),
UpperLimit = c(1.268857, 6.148088))
PlotTitle = "Insert plot title here"
p = ggplot(data=df4,
aes(x = Group,y = Mean, ymin = LowerLimit, ymax = UpperLimit)) +
ggtitle(PlotTitle) +
geom_point(aes(fill=Group, color=Group), shape=22, size=3) +
geom_pointrange(aes(col=Group), fatten = 3) +
geom_hline(aes(),yintercept =1, linetype="longdash") +
geom_text(aes(-1.5, 0.8, vjust =-0.5, hjust=-0.8, size=10),label='',
check_overlap = T) +
geom_errorbar(aes(ymin=LowerLimit,
ymax=UpperLimit,col=Group),width=0.4,cex=1) +
facet_wrap(~Group,strip.position="left",nrow=2, scales= "free_y") +
theme(plot.title=element_text(aes(5, 5), hjust=0.5, size=14,face="bold"),
legend.position='none',
strip.text.y = element_text(size=10, hjust=0.5,vjust =1,lineheight=0.1, angle=270,face="bold"),
panel.background = element_blank(),
strip.background = element_rect(fill="green"),
plot.margin = margin(3.5,0.1,3.5, 0.5, "cm")) +
coord_flip()
p
which yields this image:

Related

Barplot - stacked ggplot percentage barplot starting value NOT 0%

I have a plot like this:
library(ggplot2)
library(reshape2)
library(ggh4x)
data <- data.frame(col1=c("Sample1","Sample2","Sample3","Sample4","Sample5","Sample6"),
col2=c(0.5,0.1,0.4,0.05,0.05,0.9),
col3=c(0.6,0.1,0.3,0.1,0.1,0.8),
col4=c(0.5,0.3,0.2,0.05,0.15,0.8),
col5=c("a","a","a","b","b","b"),
col6=c("c","c","c","c","c","c"))
data2 <- melt(data)
ggplot(data=data2, aes(x = variable, y = value, fill=col1))+
geom_bar(position="stack", stat="identity")+
scale_fill_manual(values=c("#e6194B","#ffe119","#f58231","#911eb4","#42d4f4","#bfef45")) +
scale_y_continuous(expand = c(0, 0),labels = scales::percent) +
facet_nested(~col6 + ~col5, scales = "free_x",space = "free_x",switch = "x") +
ggtitle("Title") +
theme_classic() +
theme(strip.text.y = element_text(angle=0),legend.position = "right",
legend.key.size = unit(0.4, 'cm'),
axis.line = element_line(colour = "black"),
axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),
strip.placement = "outside",
strip.background = element_rect(color = "white", fill = "white"),
axis.title = element_blank()) +
guides(fill=guide_legend(title=NULL, ncol = 1)) +
xlab("X axis") +
ylab("Y axis")
Which creates a barplot like this:
Please take a look
My question is simple, how can I set y-axis starting value to 10% instead of 0% (without changing the code too much). All answers are greatly appreciated! (Similar questions are checked, without success...)
While in general not recommended for bar charts one option to "set" the starting point would be to set the limits via coord_cartesian:
library(ggplot2)
library(ggh4x)
ggplot(data = data2, aes(x = variable, y = value, fill = col1)) +
geom_bar(position = "stack", stat = "identity") +
scale_fill_manual(values = c("#e6194B", "#ffe119", "#f58231", "#911eb4", "#42d4f4", "#bfef45")) +
scale_y_continuous(expand = c(0, 0), labels = scales::percent) +
facet_nested(~ col6 + ~col5, scales = "free_x", space = "free_x", switch = "x") +
ggtitle("Title") +
theme_classic() +
theme(
strip.text.y = element_text(angle = 0), legend.position = "right",
legend.key.size = unit(0.4, "cm"),
axis.line = element_line(colour = "black"),
axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1),
strip.placement = "outside",
strip.background = element_rect(color = "white", fill = "white"),
axis.title = element_blank()
) +
guides(fill = guide_legend(title = NULL, ncol = 1)) +
xlab("X axis") +
ylab("Y axis") +
coord_cartesian(ylim = c(.1, NA))

Increase Vertical Spacing between Legend Key in ggplot2

How can I increase vertical spacing between legend keys:
p1 <- ggplot(data = HSS, mapping = aes(x = EVENT, y = HSS, fill = TIME)) +
geom_bar(stat = "identity",width=0.7, colour = "black", position = position_dodge(0.7)) +
scale_fill_manual("HSS", values = c("deepskyblue3", "indianred2"),
labels = c("1200 UTC (0.049)", "0000 UTC (0.031)")) + theme_bw()
p1 <- p1 + scale_y_continuous(expand = expansion(mult = c(0.0085, -0.085)),
limits = c(-0.03,0.5), breaks = c(-0.03,-0.01, 0.01, 0.03, 0.05, 0.07,0.09,0.11,0.13,0.15,0.17,
0.19, 0.21,0.23,0.25,0.27,0.29,0.31,0.33,0.45),
labels = c("-0.03","-0.01","0.01","0.03","0.05","0.07","0.09","0.11","0.13","0.15","0.17",
"0.19","0.21","0.23","0.25","0.27","0.29","0.31","0.33","0.45")) +
theme(axis.text.x=element_text(color = "black", size=12, face = "bold", angle=90, vjust=.5,
hjust=0.8)) +
theme(axis.text.y = element_text(color = "black", size=12, face = "bold"))
p1 <- p1 + theme( axis.line = element_line(colour = "black", size = 0.5, linetype = "solid")) +
labs( y = "HSS")
p1 <- p1 + theme(axis.title=element_text(colour = "blue2" ,size=14,face="bold", vjust = 0.1))
p1 <- p1 + theme(legend.position=c(0.98,0.98)) + theme(legend.title=element_blank(),
legend.text = element_text(face = "bold", size = "12"),
legend.box.background = element_rect(size=0.7, linetype="solid"),
legend.justification = c("right", "top"),
legend.box.margin = margin(1, 1, 1, 1)
)
p1
I tried using legend.key.height legend.spacing.y guide but it only stretched legend keys without adding space between them. Also how can I remove alternate lables (encircled) of Y-axis keeping tickmark with plot.
After browsing ggplot2's source code for a bit, I come to the conclusion that the legend.spacing.y is only applied when the byrow = TRUE as argument to the legend.
Simplied example below.
library(ggplot2)
ggplot(iris, aes(Sepal.Width)) +
geom_density(aes(fill = Species)) +
guides(fill = guide_legend(byrow = TRUE)) +
theme(legend.spacing.y = unit(1, "cm"))
With regards to the labels, just remove the values from the breaks argument in scale_y_continuous() that you don't want to show, you're already specifying them manually.

R ggplot2: how to add legend if I use dataframe as data input?

I have tried any method online but the legend is not automatically showing up. Some previous issue says the usage of dataframe in ggplot2 is not preferable, but I have tried together() method and it doesn't work either. How to fix the bug?
Here is the data:
library(ggplot2)
library(gtable)
R = 0.01*c(7.000, 6.800, 6.620, 6.460, 6.330, 6.250, 6.200, 6.160, 6.125, 6.100)
Maturity = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
c = seq(from=0, to=0, length.out = length(R))
for (i in 1:length(R)){
for (j in 1:i){
c[i] = c[i] + 1/(1+R[j])^Maturity[j]
}
c[i] = (1-1/(1+R[i])^Maturity[i])/c[i]
}
Forward = seq(from=0, to=0, length.out = length(R))
for (i in 1:length(R)){
Forward[i] = (1+R[i+1])^2/(1+R[i])-1
}
Here is the plot code in RMarkDown:
```{R fig.width=2.7559, fig.height=2.0669291}
df = data.frame(Maturity=Maturity, ParYield=c, ForwardRate=Forward, R=R)
p = ggplot(data=df, aes(x=Maturity, y=ParYield)) +
ggtitle("Curve of Zero-coupon Yield, Par Yield, Forward Yield")+
labs(x = "Maturity (year)", y = "Par Yield") +
scale_y_continuous(breaks=seq(100*(min(na.omit(Forward), c)-0.01),
100*(max(na.omit(Forward),c)+0.01),by=0.1)/100,
sec.axis = dup_axis(),
labels = scales::number_format(accuracy = 0.005)) +
scale_x_continuous("Maturity", labels=as.character(Maturity), breaks=Maturity,
sec.axis = dup_axis()) +
theme_classic() +
geom_line(aes(y=ParYield), size=1) +
geom_line(aes(y=R), size=1) +
geom_line(aes(y=ForwardRate), size=1) +
geom_point(aes(y=ParYield), shape=21, fill=rgb(69/255, 117/255, 180/255),
size=3, stroke=1.5, color="black") +
geom_point(aes(y=R), shape=22, fill=rgb(145/255, 191/255, 219/255),
size=3, stroke=1.5, color="black") +
geom_point(aes(y=ForwardRate), shape=23, fill=rgb(224/255, 243/255, 248/255),
size=3, stroke=1.5, color="black") +
theme(plot.title = element_text(size=14, hjust=0.5),
text = element_text(size=15, colour = "black", family = "Calibri"),
axis.ticks.length = unit(-0.25, 'cm'),
axis.line = element_line(size=1),
axis.ticks = element_line(size=1),
axis.text.x = element_text(margin = margin(t=15)),
axis.text.x.top = element_text(margin = margin(b=15)),
axis.text.y.right = element_text(margin = margin(l=15, r=5)),
axis.text.y = element_text(margin = margin(l=5, r=15)),
axis.title.x.top = element_blank(),
axis.title.y.right = element_blank())+
guides(colour=guide_legend(override.aes = list(pch=c(16,21,20),fill=c('r','r','r'))))+
theme(legend.position = c(0.8,0.8), legend.justification = c("right", "top"))
p
Check this sketch and make the necessary adjustments as I am not clear on how colors must be set. Pay attention to the suggestion from #stefan and modify next code:
library(ggplot2)
#Code
df = data.frame(Maturity=Maturity, ParYield=c, ForwardRate=Forward, R=R)
ggplot(data=df, aes(x=Maturity, y=ParYield)) +
ggtitle("Curve of Zero-coupon Yield, Par Yield, Forward Yield")+
labs(x = "Maturity (year)", y = "Par Yield") +
scale_y_continuous(breaks=seq(100*(min(na.omit(Forward), c)-0.01),
100*(max(na.omit(Forward),c)+0.01),by=0.1)/100,
sec.axis = dup_axis(),
labels = scales::number_format(accuracy = 0.005)) +
scale_x_continuous("Maturity", labels=as.character(Maturity), breaks=Maturity,
sec.axis = dup_axis()) +
theme_classic() +
geom_line(aes(y=ParYield), size=1) +
geom_line(aes(y=R), size=1) +
geom_line(aes(y=ForwardRate), size=1) +
geom_point(aes(y=ParYield,colour='ParYield'), shape=21, fill=rgb(69/255, 117/255, 180/255),
size=3, stroke=1.5,show.legend = T) + #Black
geom_point(aes(y=R,colour='R'), shape=22,
fill=rgb(145/255, 191/255, 219/255),
size=3, stroke=1.5) + #Black
geom_point(aes(y=ForwardRate,colour='ForwardRate'), shape=23,
fill=rgb(224/255, 243/255, 248/255),
size=3, stroke=1.5) +
theme(plot.title = element_text(size=14, hjust=0.5),
text = element_text(size=15, colour = "black", family = "Calibri"),
axis.ticks.length = unit(-0.25, 'cm'),
axis.line = element_line(size=1),
axis.ticks = element_line(size=1),
axis.text.x = element_text(margin = margin(t=15)),
axis.text.x.top = element_text(margin = margin(b=15)),
axis.text.y.right = element_text(margin = margin(l=15, r=5)),
axis.text.y = element_text(margin = margin(l=5, r=15)),
axis.title.x.top = element_blank(),
axis.title.y.right = element_blank())+
guides(colour=guide_legend(override.aes = list(pch=c(16,21,20))))+
theme(legend.position = c(0.8,0.8), legend.justification = c("right", "top"))+
labs(color='Variable')
Output:
Other option would be:
#Code 2
df = data.frame(Maturity=Maturity, ParYield=c, ForwardRate=Forward, R=R)
ggplot(data=df, aes(x=Maturity, y=ParYield)) +
ggtitle("Curve of Zero-coupon Yield, Par Yield, Forward Yield")+
labs(x = "Maturity (year)", y = "Par Yield") +
scale_y_continuous(breaks=seq(100*(min(na.omit(Forward), c)-0.01),
100*(max(na.omit(Forward),c)+0.01),by=0.1)/100,
sec.axis = dup_axis(),
labels = scales::number_format(accuracy = 0.005)) +
scale_x_continuous("Maturity", labels=as.character(Maturity), breaks=Maturity,
sec.axis = dup_axis()) +
theme_classic() +
geom_line(aes(y=ParYield), size=1) +
geom_line(aes(y=R), size=1) +
geom_line(aes(y=ForwardRate), size=1) +
geom_point(aes(y=ParYield,colour='ParYield'), shape=21,
fill=rgb(69/255, 117/255, 180/255),
size=3, stroke=1.5,show.legend = T) +
geom_point(aes(y=R,colour='R'), shape=22,
fill=rgb(145/255, 191/255, 219/255),
size=3, stroke=1.5) +
geom_point(aes(y=ForwardRate,colour='ForwardRate'), shape=23,
fill=rgb(224/255, 243/255, 248/255),
size=3, stroke=1.5) +
scale_color_manual(values = c('black','black','black'))+
theme(plot.title = element_text(size=14, hjust=0.5),
text = element_text(size=15, colour = "black", family = "Calibri"),
axis.ticks.length = unit(-0.25, 'cm'),
axis.line = element_line(size=1),
axis.ticks = element_line(size=1),
axis.text.x = element_text(margin = margin(t=15)),
axis.text.x.top = element_text(margin = margin(b=15)),
axis.text.y.right = element_text(margin = margin(l=15, r=5)),
axis.text.y = element_text(margin = margin(l=5, r=15)),
axis.title.x.top = element_blank(),
axis.title.y.right = element_blank())+
guides(colour=guide_legend(override.aes = list(pch=c(16,21,20))))+
theme(legend.position = c(0.8,0.8), legend.justification = c("right", "top"))+
labs(color='Variable')
Output:
You need to map some additional aesthetics to variables in your data. I accomplished this by pivoting your data to a longer format.
library(tidyr)
df2 <- df %>% pivot_longer(-Maturity, names_to = "Yield", values_to = "Rate")
Then, I only used one geom_line and one geom_point, but with the new Yield variable mapped to group, fill, and shape. Now you can use scale_shape_manual and scale_fill_manual to set the appearances the way you want.
p = ggplot(data=df2, aes(x = Maturity, y = Rate, group = Yield,
fill = Yield, shape = Yield)) +
ggtitle("Curve of Zero-coupon Yield, Par Yield, Forward Yield")+
labs(x = "Maturity (year)", y = "Yield") +
scale_y_continuous(breaks=seq(100*(min(na.omit(Forward), c)-0.01),
100*(max(na.omit(Forward),c)+0.01),by=0.1)/100,
sec.axis = dup_axis(),
labels = scales::number_format(accuracy = 0.005)) +
scale_x_continuous("Maturity", labels=as.character(Maturity), breaks=Maturity,
sec.axis = dup_axis()) +
theme_classic() +
geom_line(size=1) +
geom_point(size=3, stroke=1.5, color="black") +
scale_shape_manual(values = c("ParYield" = 21, "R" = 22, "ForwardRate" = 23),
labels = c("Par Yield", "Zero-coupon Yield", "Forward Yield")) +
scale_fill_manual(values = c("ParYield" = rgb(69/255, 117/255, 180/255),
"R" = rgb(145/255, 191/255, 219/255),
"ForwardRate" = rgb(224/255, 243/255, 248/255)),
labels = c("Par Yield", "Zero-coupon Yield", "Forward Yield")) +
theme(plot.title = element_text(size=14, hjust=0.5),
text = element_text(size=15, colour = "black", family = "Calibri"),
axis.ticks.length = unit(-0.25, 'cm'),
axis.line = element_line(size=1),
axis.ticks = element_line(size=1),
axis.text.x = element_text(margin = margin(t=15)),
axis.text.x.top = element_text(margin = margin(b=15)),
axis.text.y.right = element_text(margin = margin(l=15, r=5)),
axis.text.y = element_text(margin = margin(l=5, r=15)),
axis.title.x.top = element_blank(),
axis.title.y.right = element_blank())+
guides(colour=guide_legend(override.aes = list(pch=c(16,21,20),fill=c('r','r','r'))))+
theme(legend.position = c(0.8,0.8), legend.justification = c("right", "top"))
I would recommend rethinking your y axis labels.'

How to change certain aesthetics of facet_grid ggplot?

I created this plot using facet_grid and patchwork because I needed to have a customized secondary y-axis for each of the parameter and they all have different scale. I have successfully tweaked most of the aesthetics to match with what I need for the graph except for a couple of places:
Matching color with "site." I would like to match red, blue, and green to Port, Bluff, and Palm respectively. It didn't work with the code I have in scale_color_manual.
Renaming the strip text. I tried using expression(paste()) before but it wasn't working, especially with greek letter. I would like to have these respective stip text on the right for each row: ETR[max], ɑ, and E[k].
Letter in the [] are subscripts.
Thank you for any pointers. I ran out of things to try to make this week, especially with the strip texts.
My dataframe: data file
My codes are:
abrv_mo <- with (params, month.abb[month]) params <- transform(params, month = abrv_mo) params <- params[order(match(params$month, month.abb)), ] params$month <- factor(params$month, month.abb, ordered = TRUE) params$month<- as.Date(ISOdate(2019, as.numeric(params$month), 15))
p1 <- ggplot() + geom_hline(yintercept = 19.6, linetype = "dashed")
+ geom_line(data = tmpr2,
aes(month, tmp*0.98),
alpha = 0.4) + geom_errorbar(data = subset(params, variable == "max"),
aes(x= month, ymin = mean - se, ymax = mean +se, color = site),
width = 8) + geom_point(data = subset(params, variable == "max"),
aes(x=month, y=mean, color = site, group=site),
size = 2.5) + facet_grid(rows = vars(variable),
cols = vars(site),
switch = "y", scale = "free_y") + scale_x_date(name = NULL, date_labels = "%b",
seq(as.Date("2019-01-15"),
as.Date("2019-07-15"), by = "1 month")) + # ?strftime() for more options scale_y_continuous(limits = c(5,40), breaks = seq(5, 40, by = 15),
expand = c(0,0),
sec.axis = sec_axis(~./0.98)) + scale_color_manual(name = "Site",
labels = c("Port", "Bluff", "Palm"),
values = c("#FC4E07","#00AFBB", "#C3D7A4")) + theme_bw() + theme(plot.background = element_blank(),
strip.background = element_blank(),
strip.placement = "outside",
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_rect(size=1, colour = "black"),
panel.spacing = unit(0.3, "lines"),
axis.line = element_line(size=0.1, colour = "black"),
axis.ticks.y = element_line(size=0.5, colour = "black"),
axis.text.x = element_blank(),
axis.text.y = element_text(size=10, color="black", margin = margin(t = 0.5, l = 0.5)),
text = element_text(size = 18),
legend.position="none",
plot.margin=margin(l = -1, unit = "cm")) + ylab(NULL)
p2 <- ggplot() + geom_hline(yintercept = 0.16, linetype = "dashed")
+ geom_line(data = tmpr2,
aes(month, tmp*0.008),
alpha = 0.4) + geom_errorbar(data = subset(params, variable=="slope"),
aes(x= month, ymin = mean - se, ymax = mean +se, color = site),
width = 8) + geom_point(data = subset(params, variable == "slope"),
aes(x=month, y=mean, color=site, group=site),
size = 2.5) + facet_grid(rows = vars(variable),
cols = vars(site),
switch = "y",
scale = "free_y") + scale_x_date(name = NULL, date_labels = "%b",
seq(as.Date("2019-01-15"),
as.Date("2019-07-15"), by = "1 month")) + # ?strftime() for more options scale_y_continuous(breaks = seq(0.15,
0.26, by = 0.05),
expand = c(0,0),
limits = c(0.15,0.26),
sec.axis = sec_axis(~./0.008, name = "Temperature (°C)")) + scale_color_manual(name = "Site",
labels = c("Port", "Bluff", "Palm"),
values = c("#FC4E07","#00AFBB", "#C3D7A4")) + theme_bw() + theme(plot.background = element_blank(),
strip.background = element_blank(),
strip.placement = "outside",
strip.text.x = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_rect(size=1, colour = "black"),
panel.spacing = unit(0.3, "lines"),
axis.line = element_line(size=0.1, colour = "black"),
axis.ticks.y = element_line(size=0.5, colour = "black"),
axis.text.x = element_blank(),
axis.text.y = element_text(size=10, color="black", margin = margin(t = 0.5, l = 0.5)),
axis.text.y.right = element_text(size=10, color="black", margin = margin(t = 0.5, r = 10)),
text = element_text(size = 18),
legend.position="none",
plot.margin=margin(l = -1.5, unit = "cm")) + ylab(NULL)
p3 <- ggplot() + geom_hline(yintercept = 140, linetype = "dashed") + geom_line(data = tmpr2,
aes(month, tmp*7),
alpha = 0.4) + geom_errorbar(data = subset(params, variable=="ek"),
aes(x= month, ymin = mean - se, ymax = mean +se, color = site),
width = 8) + geom_point(data = subset(params, variable=="ek"),
aes(x=month, y=mean, color=site, group=site),
size = 2.5) + facet_grid(rows = vars(variable),
cols = vars(site),
switch = "y",
scale = "free_y") + scale_x_date(name = NULL, date_labels = "%b",
seq(as.Date("2019-01-15"),
as.Date("2019-07-15"), by = "1 month")) + # ?strftime() for more options scale_y_continuous(expand = c(0,0),
breaks = seq(25, 250, by = 100),
limits = c(25,250),
sec.axis = sec_axis(~./7)) + scale_color_manual(name = "Site",
labels = c("Port", "Bluff", "Palm"),
values = c("#FC4E07","#00AFBB", "#C3D7A4")) + theme_bw() + theme(plot.background = element_blank(),
strip.background = element_blank(),
strip.placement = "outside",
strip.text.x = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_rect(size=1, colour = "black"),
panel.spacing = unit(0.3, "lines"),
axis.line = element_line(size=0.1, colour = "black"),
axis.ticks.y = element_line(size=0.5, colour = "black"),
axis.text.x = element_text(angle = 45,size=10, color="black", hjust = 1,
margin = margin(t = 0.5, r = 0.5)),
axis.text.y = element_text(size=10, color="black", margin = margin(t = 0.5, l = 0.5)),
text = element_text(size = 18),
legend.position="none",
plot.margin=margin(l = -1.5, unit = "cm")) + ylab(NULL)
library(patchwork)
p1 + p2 + p3 + plot_layout(ncol = 1)

Layout of plots with a unique legend using ggplot

I was trying to create a layout with plots sharing the same legend. The legend is on the top of the first plot, however, the next plot has a different scale. How can I solve this?
library(ggplot2)
library(gridExtra)
grid.arrange(
ggplot(mpg, aes(displ, cty)) +
geom_point(aes(shape = "Data")) +
stat_smooth(aes(linetype = "Regression"), method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
scale_shape_manual(values = 1) +
labs(shape = "", linetype = "") +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10),
legend.position = "top")
,
ggplot(mpg, aes(displ, cty)) +
geom_point(shape = 1) +
stat_smooth(method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10))
)
If the plots also have the same axes labels, facet_wrap may be a good option.
library(ggplot2)
data = rbind(data.frame("id" = 1, mpg), data.frame("id" = 2, mpg))
ggplot(data, aes(displ, cty)) +
geom_point(aes(shape = "Data")) +
stat_smooth(aes(linetype = "Regression"), method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
scale_shape_manual(values = 1) +
labs(shape = "", linetype = "") +
theme_classic() +
facet_wrap(~id, ncol = 1 ) +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10),
legend.position = "top",
strip.background = element_blank(),
strip.text.x = element_blank()) #these two lines remove the facet strips
grid.arrange doesn't try to align plot panels; it's a generic function meant for all kinds of grid graphics, and in this case since the top plot has a legend it gets shrunk to fit in the available space (by default 1/2 of the page here). For the specific case of ggplots I would use egg::ggarrange,
library(ggplot2)
library(egg)
ggarrange(
ggplot(mpg, aes(displ, cty)) +
geom_point(aes(shape = "Data")) +
stat_smooth(aes(linetype = "Regression"), method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
scale_shape_manual(values = 1) +
labs(shape = "", linetype = "") +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10),
legend.position = "top")
,
ggplot(mpg, aes(displ, cty)) +
geom_point(shape = 1) +
stat_smooth(method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10))
)
I don't know how to use grid.arrange, but here's a solution using my cowplot package. The idea is to separate the legend out from the plot and then put the three elements into one column. A similar approach would work with grid.arrange, I assume.
library(cowplot)
p1 <- ggplot(mpg, aes(displ, cty)) +
geom_point(aes(shape = "Data")) +
stat_smooth(aes(linetype = "Regression"), method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
scale_shape_manual(values = 1) +
labs(shape = "", linetype = "") +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10),
legend.position = "top")
p2 <- ggplot(mpg, aes(displ, cty)) +
geom_point(shape = 1) +
stat_smooth(method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10))
legend <- get_legend(p1)
plot_grid(legend, p1 + theme(legend.position = "none"), p2,
ncol=1, rel_heights = c(0.1, 1, 1))

Resources