I created a ggplot2 object:
a <- replicate(8,rnorm(100))
colnames(a) <- letters[1:8]
b < -melt(a,id.vars=1:1)
colnames(b) <- c("c","variable","value")
ggplot(b,aes(x = c,y = value, colour = variable, linetype = variable)) +
geom_line()+
geom_point(aes(shape = factor(variable)), size = 1.7) +
scale_x_continuous(limits = c(-1, 1),
breaks = seq(-1, 1, 0.1),
expand=c(0.01, 0.01)) +
scale_y_continuous(limits = c(-1, 1),
breaks = seq(-1, 1, 0.1),
expand = c(0.01, 0.01))+
theme_bw(base_size = 12, base_family = "Helvetica") +
theme(axis.text=element_text(size = 10),
axis.title=element_text(size = 10),
text = element_text(size = 10),
axis.line = element_line(size = 0.25),
axis.ticks=element_line(size = 0.25),
panel.grid.major = element_blank(),
#panel.grid.minor = element_blank(),
panel.border = element_rect(colour = "black", fill = NA, size = 0.5),
panel.background = element_blank(),
legend.position = "top" ,
legend.direction = "vertical",
legend.title = element_blank(),
legend.text = element_text(size = 13),
legend.background = element_blank(),
legend.key = element_blank()) +
labs(x = '', y = '', title = "") +
theme(plot.title = element_text(size=10)) +
theme(strip.text.x = element_text(size = 8,color="black"),
strip.background = element_blank()) +
theme(strip.text.x = element_text(size = 8, colour = "black"))
My problem is the following:
when I create the legend, there is a separate legend for the colors and a separate one for the points.
How can I create a single legend for each of the 8 variables?
Let me minimise your code and focus on the legend issue. This is what you have now.
ggplot(b,aes(x = c, y = value, colour = variable, linetype = variable)) +
geom_line() +
geom_point(aes(shape = factor(variable)),size=1.7)
Your data frame, b has variable as factor. You use this in two ways here; variable and factor(variable). You can simply use variable for shape in geom_point; make all variable identical.
ggplot(b,aes(x = c, y = value, colour = variable, linetype = variable)) +
geom_line()+
geom_point(aes(shape = variable),size = 1.7)
I saw some warning messages related to colours and other things. You may want to take care of them. But, for legend, this is one way to go.
Take from the ideas on this page: http://www.cookbook-r.com/Graphs/Legends_(ggplot2)/#modifying-the-text-of-legend-titles-and-labels
I edited your code to make the data visible (you had problems with your x-axis limits. Note the final three lines. These commands tell ggplot to create only one legend.
a<-replicate(6,rnorm(100))
colnames(a)<-letters[1:6]
b<-melt(a,id.vars=1:1)
colnames(b)<-c("c","variable","value")
ggplot(b,aes(x=c,y=value,colour=variable,linetype=variable)) +
geom_line() + geom_point(aes(shape=factor(variable)),size=1.7)+
scale_x_continuous(limits=c(0,100))+
scale_y_continuous(limits=c(-2,2),breaks=seq(-2,2,0.1),expand=c(0.01,0.01))+
theme_bw(base_size=12, base_family="Helvetica") +
theme(axis.text=element_text(size=10),
axis.title=element_text(size=10),
text = element_text(size=10),
axis.line = element_line(size=0.25),
axis.ticks=element_line(size=0.25),
panel.grid.major = element_blank(),
#panel.grid.minor = element_blank(),
panel.border = element_rect(colour="black",fill=NA,size=0.5),
panel.background = element_blank(),
legend.position="top" ,
legend.direction="vertical",
legend.title=element_blank(),
legend.text=element_text(size=13),
legend.background=element_blank(),
legend.key=element_blank())+
labs(x='', y='',title="")+
theme(plot.title=element_text(size=10))+
theme(strip.text.x = element_text(size = 8,color="black"),strip.background=element_blank())+
theme(strip.text.x = element_text(size = 8,color="black"))+
scale_colour_discrete(name ="Factor")+
scale_linetype_discrete(name ="Factor") +
scale_shape_discrete(name ="Factor")
Related
I'm using ggplot to graph a forest plot. I have used facet labels to label groups (in example below Test1, Test2, Test3). Is there a way to slightly shift the actual position of the facet label/strip to the left (as indicated by the arrows in my picture below)?
I can shift the position of the text within the facet label but I think I have done that as much as possible. Thus, I think I need to shift the actual facet label (strip bar/rectangle) itself. Is this possible?
Would be very grateful if anyone could help me or point out a way to get a similar effect!
Please find reproducible code here:
library(dplyr)
library(ggplot2)
library(ggforce)
library(tidyverse)
# Reproducible dataset
df <- data.frame(outcome = c('outcome1', 'outcome1', 'outcome2','outcome2','outcome3','outcome3','outcome4','outcome4','outcome5','outcome5'),
type = c('Test1','Test1','Test2','Test2', 'Test3', 'Test3', 'Test3','Test3', 'Test3', 'Test3'),
Coef = c(0.10026935, 0.10026935, 0.13713358, 0.13713358,0.07753188,0.07753188,0.09193794,0.09193794,0.06170916,0.06170916),
CIr_low = c(0.070955475,0.070955475,0.108705781,0.108705781,0.052595474,0.052595474,0.056340327,0.056340327,0.036185918,0.036185918),
CIr_high = c(0.12958323,0.12958323,0.16556139,0.16556139,0.10246828,0.10246828,0.12753555,0.12753555,0.08723240,0.08723240),
model = c(1,2,1,2,1,2,1,2,1,2))
# Set type as factor
df <- df %>% mutate(type = fct_relevel(type, "Test1","Test2","Test3"))
# Plot with ggplot
ggplot(df, aes(x = outcome, y = Coef, ymin = CIr_low,ymax =CIr_high,fill = as.factor(type))) +
geom_errorbar(aes(x= outcome, ymin=CIr_low, ymax=CIr_high), width=0.2,cex=0.5)+
geom_point(shape = 18, size = 5)+
facet_grid(type ~ ., scales = "free", space = "free") +
geom_hline(yintercept = 0, linetype = 'dashed', col = 'black') +
scale_y_continuous(limits = c(-0.1, 0.25)) +
ggforce::facet_col(facets = type ~ ., scales = "free_y", space = "free", strip.position = "top")+
theme_bw()+
coord_flip() +
xlab('Group')+
ylab(expression("Standardized" ~ beta *" (95%CI)"))+
theme(line = element_line(colour = "black", size = 0.5),
plot.margin = margin(0.5, 0.5, 0.5, 0.5, unit = "cm"),
strip.background = element_rect(colour = "white", fill="white"),
strip.text = element_text(colour = "black",face="italic"),
strip.text.x = element_text(size = 12,angle = 0,hjust = 0,face="bold.italic", color="darkblue"),
legend.position ="none",
axis.line.x = element_line(colour = "black"),
axis.line.y = element_blank(),
panel.border= element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
panel.spacing = unit(2, "lines"),
axis.ticks = element_blank(),
axis.title.x = element_text(colour = "black"),
axis.title.y = element_blank(),
axis.text=element_text( color = "black")
)
You can try:
ggplot(df, aes(x = outcome, y = Coef, ymin = CIr_low,ymax =CIr_high,fill = as.factor(type))) +
geom_errorbar(aes(x= outcome, ymin=CIr_low, ymax=CIr_high), width=0.2,cex=0.5)+
geom_point(shape = 18, size = 5, show.legend = F)+
geom_hline(yintercept = 0, linetype = 'dashed', col = 'black') +
scale_y_continuous(expression("Standardized" ~ beta *" (95%CI)"),limits = c(-0.1, 0.25)) +
xlab("")+
coord_flip() +
facet_grid(type~., scales = "free", space = "free_y", switch = "y") +
theme_minimal() +
theme(strip.placement = "outside",
strip.text.y.left = element_text(angle = 0,vjust = 1,size=12))
Or use a cowplot approach with ggtitle
plots <- df %>%
split(.$type) %>%
map2(.,names(.), ~ggplot(.x, aes(x = outcome, y = Coef, ymin = CIr_low,ymax =CIr_high,fill = as.factor(type))) +
geom_errorbar(aes(x= outcome, ymin=CIr_low, ymax=CIr_high), width=0.2, size=0.5)+
geom_point(shape = 18, size = 5, show.legend = F)+
geom_hline(yintercept = 0, linetype = 'dashed', col = 'black') +
scale_y_continuous(limits = c(-0.1, 0.25))+
coord_flip() +
xlab('')+
ylab(expression("Standardized" ~ beta *" (95%CI)"))+
ggtitle(.y)+
theme_minimal(base_size = 12)+
theme( panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
plot.title.position = "plot"))
cowplot::plot_grid(plots$Test1 + theme(axis.title.x = element_blank(), axis.ticks.x = element_blank(), axis.text.x = element_blank()),
plots$Test2 + theme(axis.title.x = element_blank(), axis.ticks.x = element_blank(), axis.text.x = element_blank()),
plots$Test3, ncol = 1)
I want to produce chart like this:
I go with this code:
dat <- data.frame(
name1 = c("A", "B", "C", "D", "E"),
name2 = c("F", "G", "H", "I", "J"),
value = c(-12,10,5,-7,-2)
)
ggplot(dat,aes(x = name1,y = value)) +
geom_bar(stat = "identity",
fill = "#465978",
width = 0.3) +
ylim(-50,50) +
geom_hline(yintercept = 0,
color = "#9e9e9e",
alpha = 0.3,
linetype = "dotted") +
coord_flip() +
theme_bw() +
theme(axis.line = element_blank(),
axis.title = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_text(colour = "#737373"),
axis.ticks = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank())
and ended up like this: (note: there is a line in the middle, if you can't see, may be due to low resolution)
How to add dat$name2 in the right side (i.e. top x axis)?
If you don't mind, maybe you can help me produce more similar chart?
Offering an alternative to r2evans' solution, you can convert a discrete variable to a continuous one by doing match(x, unique(x)). If you then have continuous variables on both axes, it is easy to add a secondary axis.
Here is how you could do that (with some extra decorations based on your request to make the chart more similar).
library(ggplot2)
dat <- data.frame(
name1 = c("A", "B", "C", "D", "E"),
name2 = c("F", "G", "H", "I", "J"),
value = c(-12,10,5,-7,-2)
)
# Probably easiest to define `cont_name1 = match(name1, unique(name1))` in the data
# instead of having to declare it in the `aes()` every time.
ggplot(dat,aes(x = value,y = match(name1, unique(name1)))) +
geom_tile(width = Inf, height = 0.3, fill = "grey95") +
geom_bar(stat = "identity",
fill = "#465978",
width = 0.3, orientation = "y") +
geom_segment(aes(y = match(name1, unique(name1)) - 0.15,
yend = match(name1, unique(name1)) + 0.3,
xend = value)) +
geom_text(aes(x = ifelse(value < 0, value - 4, value + 4),
y = match(name1, unique(name1)) + 0.2,
label = scales::percent(value, scale = 1, accuracy = 1)),
vjust = 0) +
xlim(-50,50) +
scale_y_continuous(
breaks = match(dat$name1, unique(dat$name1)),
labels = dat$name1,
sec.axis = sec_axis(~ .x, labels = dat$name2, breaks = 1:5)
) +
geom_vline(xintercept = 0,
color = "#9e9e9e",
alpha = 0.3,
linetype = "dotted") +
ggtitle("Title here (0%)") +
theme_bw() +
theme(axis.line = element_blank(),
axis.title = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_text(colour = "#737373"),
axis.ticks = element_blank(),
plot.title = element_text(hjust = 0.5, colour = "grey60"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank())
Created on 2021-01-17 by the reprex package (v0.3.0)
Normally (with a continuous scale) I'd recommend scale_y_continuous(sec.axis=...). Unfortunately, scale_discrete does not yet support it (see https://github.com/tidyverse/ggplot2/issues/3171). With that, the two ways to go include geom_text and annotations. I'll offer the first.
To make it consistent on both sides, we'll need to remove the axis labels from the left axis. (I find this annoying, but consistency between axes is important to me. If it is not as much to you, then you can reduce some of the changes.)
ggplot(dat,aes(x = name1,y = value)) +
geom_bar(stat = "identity",
fill = "#465978",
width = 0.3) +
ylim(-50,50) +
geom_hline(yintercept = 0,
color = "#9e9e9e",
alpha = 0.3,
linetype = "dotted") +
geom_text(aes(y = -Inf, label = name1), hjust = 0, colour = "#737373") + # new
geom_text(aes(y = Inf, label = name2), hjust = 1, colour = "#737373") + # new
coord_flip() +
theme_bw() +
theme(axis.line = element_blank(),
axis.title = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(), # change
axis.ticks = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank())
One problem you will run into with multi-line labels (as in your example) is that of alignment. ggplot2 has a confounded sense of hjust=, where it means both direction of the text box from the point and alignment of the text within the text box. So hjust=0 means "text goes to the right of the point, and the text is left-aligned". There does not seem to be an easy way to have the text box go to the right of the point (first geom_text, on the left-edge) yet have the text right-justified. (I'll be happy if somebody can show an easy way to work around this!)
The workarounds to force that left-edge right-align textbox require knowing a priori the dimensions of the plot so that you can hard-position the text box (not y=-Inf, the left-edge) within the plot boundary and hard-code the limits of the plot. (Know that when you form the plot, none of the functions know what the dimensions of the rendered plot will be, in user-points, centimeters, or similar.)
As an aside, we can add a geom_text and geom_tile for a couple more features.
ggplot(dat,aes(x = name1,y = value)) +
geom_tile(height = 90, width = 0.3, fill = "gray90") +
geom_bar(stat = "identity",
fill = "#465978",
width = 0.3) +
ylim(-50,50) +
geom_hline(yintercept = 0,
color = "#9e9e9e",
alpha = 0.3,
linetype = "dotted") +
geom_text(aes(y = -Inf, label = name1), hjust = 0, colour = "#737373") +
geom_text(aes(y = Inf, label = name2), hjust = 1, colour = "#737373") +
geom_text(aes(label = value), vjust = -1.1) +
coord_flip() +
theme_bw() +
theme(axis.line = element_blank(),
axis.title = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank())
. + > ggplot(dat,aes(x = name1,y = value)) +
geom_tile(aes(y = 0), height = 90, width = 0.3, fill = "gray90") +
geom_bar(stat = "identity",
fill = "#465978",
width = 0.3) +
ylim(-50,50) +
geom_hline(yintercept = 0,
color = "#9e9e9e",
alpha = 0.3,
linetype = "dotted") +
geom_text(aes(y = -Inf, label = name1), hjust = 0, colour = "#737373") +
geom_text(aes(y = Inf, label = name2), hjust = 1, colour = "#737373") +
geom_text(aes(label = value), vjust = -1.1) +
coord_flip() +
theme_bw() +
theme(axis.line = element_blank(),
axis.title = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank())
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)
Hello I will try for a last time,
I am doing my best to draw a barplot like the following Figure:
However it seems impossible with R.
Any idea?
Thanks in advance,
Peter
Attached the code I used.
groupe2<-rep(c(rep("P",4),rep("I",4)),2)
groupe<-rep(c("PPP","PPI","PIP","PII","IPP","IPI","IIP","III"),2)
OR_A<-c(1.00,0.86,0.88,0.90,0.77,0.68,0.77,0.70)
ICinf_A<-c(NA,0.70,0.72,0.76,0.60,0.50,0.61,0.61)
ICsup_A<-c(NA,1.06,1.07,1.06,1.00,0.92,0.96,0.81)
OR_B<-c(1.00,0.97,1.01,0.81,0.73,0.69,0.61,0.58)
ICinf_B<-c(NA,0.78,0.77,0.62,0.61,0.57,0.50,0.52)
ICsup_B<-c(NA,1.20,1.28,1.05,0.81,0.82,0.71,0.65)
OR_C<-c(1.00,1.03,0.86,0.65,0.68,0.58,0.47,0.37)
ICinf_C<-c(NA,0.84,0.67,0.50,0.59,0.49,0.40,0.33)
ICsup_C<-c(NA,1.27,1.10,0.86,0.78,0.69,0.56,0.41)
Cohort<-c(rep(" PC",8), rep("RIC",8))#, rep("RIC",8))
OR<-c(OR_A,OR_B)#,OR_C)
ICinf<-c(ICinf_A,ICinf_B)#,ICinf_C)
ICsup<-c(ICsup_A,ICsup_B)#,ICsup_C)
rm(dataOR)
dataOR<-data.frame(OR,groupe,Cohort,groupe2,ICinf,ICsup)
names(dataOR)
dataOR[, "groupe"] <- factor(dataOR[, "groupe"] ,
levels = c("PPP","PPI","PIP","PII","IPP","IPI","IIP","III"))
##########
library(ggdag)
ggplot(dataOR, aes(fill=outcome, y=OR, x=groupe)) +
geom_bar(position="dodge", stat="identity", color = "gray95", size = 0.25) +
# scale_fill_brewer(palette="Blues")+
scale_fill_manual(values = RColorBrewer::brewer.pal(5, "Blues")[3:5]) +
geom_errorbar(aes(ymin=ICinf, ymax=ICsup), width=.4, position=position_dodge(.9))+
geom_hline(yintercept=1) +
geom_point(position = position_dodge(0.9), size = 0.5, show.legend = F) +
scale_y_continuous(expand = expand_scale(mult = c(0, 0.05))) +
facet_wrap(~groupe, nrow = 1, scales = "free_x") +
labs(fill = NULL) +
theme(legend.position = "top",
legend.key.height = unit(0.2, "cm"),
legend.background = element_rect(color = "black", size = 0.4),
axis.line = element_line(color = "black"),
axis.text.x = element_blank(),
axis.ticks = element_blank(),
panel.grid.major.x = element_blank(),
axis.title = element_text(face = "bold"))
I would like to add two (same) legends in ggplot and also want to change legend title and labels. I have tried this:
library(ggplot2)
ggplot(ToothGrowth, aes(x = len, color=factor(dose), fill= factor(dose))) +
geom_density(alpha=0.4) +
theme(panel.background = element_rect(fill = "khaki1", colour = "darkorchid3", size = 2, linetype = "solid"),
panel.grid.major = element_line(size = 0.5, linetype = 'solid', colour = "white"),
panel.grid.minor = element_line(size = 0.25, linetype = 'solid', colour = "white"),
plot.background = element_rect(fill = "bisque2"),
text = element_text(colour="blue4"), axis.title = element_text(size = rel(1.25)), axis.text = element_text(colour="blue4", size = 12),
legend.position=c(.90,.85), legend.background =
element_rect(fill="lightsalmon", colour = "tomato3", size = 1.25),
legend.title = element_text(colour="navy", face="bold"),
legend.text = element_text( colour="midnightblue", face="bold"), strip.background = element_rect(fill="olivedrab1", colour = "darkorchid3", size = 2, linetype = "solid"),
strip.text = element_text(colour="coral4", size=12, angle=0, face="bold")) +
scale_fill_discrete(name = "Dose", labels = c("A", "B", "C")) +
facet_wrap(~supp)
but I got this plot:
I want this plot:
Can somebody help me? Thank you.
As #erocoar and others have suggested, grid.arrange from gridExtra is useful here. Borrowing heavily from from the linked question:
library(gridExtra)
out <- by(data = ToothGrowth, INDICES = ToothGrowth$supp, FUN = function(m) {
m <- droplevels(m)
m <- ggplot(m, aes(x = len, fill= factor(dose)), color=factor(dose)) +
geom_density(alpha=0.4) +
theme(panel.background = element_rect(fill = "khaki1", colour = "darkorchid3",
size = 2, linetype = "solid"),
panel.grid.major = element_line(size = 0.5, linetype = 'solid',
colour = "white"),
panel.grid.minor = element_line(size = 0.25, linetype = 'solid',
colour = "white"),
plot.background = element_rect(fill = "bisque2"),
text = element_text(colour="blue4"),
axis.title = element_text(size = rel(1.25)),
axis.text = element_text(colour="blue4", size = 12),
legend.position=c(.90,.85),
legend.background = element_rect(fill="lightsalmon",
colour = "tomato3", size = 1.25),
legend.title = element_text(colour="navy", face="bold"),
legend.text = element_text( colour="midnightblue", face="bold"),
strip.background = element_rect(fill="olivedrab1",
colour = "darkorchid3", size = 2,
linetype = "solid"),
strip.text = element_text(colour="coral4", size=12, angle=0,
face="bold")) +
scale_fill_discrete(name = "Dose", labels = c("A", "B", "C")) +
xlim(0,35) +
ylim(0,0.2) +
ggtitle(m$supp)
})
do.call(grid.arrange, list(grobs = out, ncol = 2))
Some things to note.
I moved the color argument outside of the aes() call and this removed the extra legend.
I manually set the x and y limits for a consistent look.
I needed to add a title.
To get the plots side by side I had to add a second argument to do.call(). When supplying more than one argument it needs to be in a list.
I hope this helps.