How to add a legend to ggplot in R? - r

I'm trying to add a legend to my graph which consists of two lines. Unfortunately, I don't understand how. Could you help me out, please? My dataframe can be found below.
Thank you.
# dput(df)
structure(list(t = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), Beta_Treatment = c(0.999550283587599,
1.1284848818908, 1.3173797973744, 1.381630131904, 1.42558575749304,
1.598454651784, 1.68182321476, 1.908913645904, 1.9830406566956,
2.0704834391088), Beta_Control = c(0.822042496772398, 0.914170557749195,
0.812776816705598, 0.829879870335997, 0.906381000106958, 0.891107911295998,
0.885094437239998, 0.810487561695997, 0.816917509704399, 0.881900118891192
), treatment_stderr = c(0.0466078055173255, 0.0451188571313495,
0.0473857585047991, 0.0465872903741648, 0.0436607368165115, 0.0479028140228299,
0.0445418661900949, 0.0451947124622918, 0.0474264037378467, 0.0464878615840165
), control_stderr = c(0.0329566953375247, 0.0319038498369643,
0.0335067911704116, 0.0329421889406788, 0.0308728030745565, 0.0338724046334612,
0.03149585562972, 0.0319574876558628, 0.0335355316903225, 0.0328718821689198
)), class = "data.frame", row.names = c(NA, -10L))
#create and save graph as pdf
p1 <- ggplot(data=df, mapping=aes(y=Beta_Treatment, x=t)) +
geom_line(linetype="dashed", colour = "blue") +
geom_point(shape = 15) +
geom_errorbar(aes(ymin=(Beta_Treatment-1.96*treatment_stderr), ymax=(Beta_Treatment+1.96*treatment_stderr)), width=1) +
ylim(c(0,2.5)) + labs(y = "Beta") +
geom_vline(xintercept = 6) +
scale_x_continuous(limits = c(0, 11), breaks = c(0, 2, 4, 6, 8, 10)) +
theme_bw()
ggsave(last_plot(),filename = "plot.pdf")
p2 <- p1 + geom_line(aes(y=Beta_Control, x=t),linetype="dashed", colour = "green")+
geom_point(aes(y=Beta_Control, x=t), shape = 19) +
geom_errorbar(aes(ymin=(Beta_Control-1.96*control_stderr), ymax=(Beta_Control+1.96*control_stderr )), width=1) +
ylim(c(0,2.5)) +
geom_vline(xintercept = 6) +
theme_bw()
ggsave(last_plot(),filename = "plot2.pdf")

If you want a legend then you have to map on aesthetics, i.e. move color inside aes() and you will automatically get a legend. However, to set your desired colors in that case requires to set them via scale_color_manual.
To this end I map some "speaking" category labels on the color aes and assign colors and labels to these categories inside scale_color_manual. Additionally I used the limits argument to set the order of the categories:
ggplot(data = df, mapping = aes(y = Beta_Treatment, x = t)) +
geom_line(aes(colour = "treat"), linetype = "dashed") +
geom_point(shape = 15) +
geom_errorbar(aes(ymin = (Beta_Treatment - 1.96 * treatment_stderr),
ymax = (Beta_Treatment + 1.96 * treatment_stderr)), width = 1) +
ylim(c(0, 2.5)) +
labs(y = "Beta", color = NULL) +
geom_vline(xintercept = 6) +
scale_x_continuous(limits = c(0, 11), breaks = c(0, 2, 4, 6, 8, 10)) +
theme_bw() +
geom_line(aes(y = Beta_Control, color = "control"), linetype = "dashed") +
geom_point(aes(y = Beta_Control), shape = 19) +
geom_errorbar(aes(ymin = (Beta_Control - 1.96 * control_stderr),
ymax = (Beta_Control + 1.96 * control_stderr)), width = 1) +
scale_color_manual(values = c(treat = "blue", control = "green"),
labels = c(treat = "Treatment", control = "Control"),
limits = c("treat", "control"))

Related

Create a special Radial bar chart (race track plot)

I was able to replicate another good answers here to create a basic radial plot, but can anyone give me any clue of others functions/parameters/ideas on how to convert the basic one to something similar to this :
You could get pretty close like this:
df <- data.frame(x = c(10, 12.5, 15), y = c(1:3),
col = c("#fcfbfc", "#fbc3a0", "#ec6f4a"))
library(ggplot2)
ggplot(df, aes(x = 0, xend = x, y = y, yend = y, color = col)) +
geom_hline(yintercept = c(1:3), size = 14, color = "#dfdfdf") +
geom_hline(yintercept = c(1:3), size = 13, color = "#f7f7f7") +
geom_segment(color = "#bf2c23", size = 14, lineend = 'round') +
geom_segment(size = 13, lineend = 'round') +
scale_color_identity() +
geom_point(aes(x = x - 0.03 * y), size = 5, color = "#bf2c23",
shape = 21, fill = 'white') +
geom_point(aes(x = x - 0.03 * y), size = 2, color = "#bf2c23",
shape = 21, fill = 'white') +
scale_y_continuous(limits = c(0, 4)) +
scale_x_continuous(limits = c(0, 20)) +
coord_polar() +
theme_void()
Here's a start. Are there particular aspects you're trying to replicate? This is a fairly customized format.
df <- data.frame(type = c("on", "ia", "n"),
radius = c(2,3,4),
value = c(10,21,22))
library(ggplot2); library(ggforce)
ggplot(df) +
geom_link(aes(x = radius, xend = radius,
y = 0, yend = value),
size = 17, lineend = "round", color = "#bb353c") +
geom_link(aes(x = radius, xend = radius,
y = 0, yend = value, color = type),
size = 16, lineend = "round") +
geom_label(aes(radius, y = 30,
label = paste(type, ": ", value)), hjust = 1.8) +
scale_x_continuous(limits = c(0,4)) +
scale_y_continuous(limits = c(0, 30)) +
scale_color_manual(values = c("on" = "#fff7f2",
"ia" = "#f8b68f",
"n" = "#e4593a")) +
guides(color = "none") +
coord_polar(theta = "y") +
theme_void()

Rstudio Bland Altman grouped colours and shapes

I have a bland-altman plot of 16 measurements divided over 3 groups (Slice) which I want to colorcode and possibly have different shapes but somehow I cant get it working:
df <- data.frame("Slice" = c(1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3),
"Segments" = c(1:16),
"mean" = c(6,5,2,4,8,9,6,3,5,6,5,8,5,4,6,4),
"dif" = c(1,3,2,1,2,3,2,1,2,2,2,1,3,2,1,2))
#creat limits of agreement
LL = mean(df$dif)-1.96*(sd(df$dif))
UL = mean(df$dif)+1.96*(sd(df$dif))
#create BA plot
BAplot <- ggplot(df, aes(x=mean,y=dif))+
geom_jitter(alpha=1.0,size=18,shape="*", stroke = 1.5)+
geom_hline(yintercept=mean(df$dif),color= "blue",size=2)+
geom_text(aes(x = 12, y = mean(df$dif)+0.2, label = round(mean(df$dif), 1)), col = "blue", size = 7) +
geom_hline(yintercept=0,linetype=3,size=2) +
geom_hline(yintercept=c(UL,LL),color="black",linetype="dashed",size=2)+theme_bw()+
geom_text(aes(x = 12, y = UL+0.2, label = round(UL,1)), col = "black", size = 7) +
geom_text(aes(x = 12, y = LL+0.2, label = round(LL,1)), col = "black", size = 7) +
scale_x_continuous("mean",limits = c(-2,12))+
scale_y_continuous("diff", limits = c(-1, 5.5))
To code your points by color and to have different shapes you have to map your Slice column on the color and/or shape aesthetic inside geom_jitter. As Slice is a numeric I first converted it to a factor. If you want specific colors or shape you could set your desired values using scale_color_manual and scale_shape_manual:
library(ggplot2)
ggplot(df, aes(x = mean, y = dif)) +
geom_jitter(aes(color = factor(Slice), shape = factor(Slice)), alpha = 1.0, size = 2) +
geom_hline(yintercept = mean(df$dif), color = "blue", size = 2) +
geom_text(aes(x = 12, y = mean(dif) + 0.2, label = round(mean(dif), 1)), col = "blue", size = 7) +
geom_hline(yintercept = 0, linetype = 3, size = 2) +
geom_hline(yintercept = c(UL, LL), color = "black", linetype = "dashed", size = 2) +
theme_bw() +
geom_text(aes(x = 12, y = UL + 0.2, label = round(UL, 1)), col = "black", size = 7) +
geom_text(aes(x = 12, y = LL + 0.2, label = round(LL, 1)), col = "black", size = 7) +
scale_x_continuous("mean", limits = c(-2, 12)) +
scale_y_continuous("diff", limits = c(-1, 5.5))

ggplot lines not through shapes

I want to create a line plot with the shapes varied by the Methods variable in my dataset. However, I don't want the lines to be drawn over the shapes, for example this is not good:
How do I hide the lines behind the shapes so that the lines are not through the shapes. Here is the dataset:
xx <- data.frame(
stringsAsFactors = FALSE,
rho = c(0.7,0.7,0.7,0.7,0.7,0.7,
0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,0.7,
0.7,0.7,0.7,0.7,0.7,0.7),
sample = c(1L,1L,1L,1L,1L,1L,1L,1L,
2L,2L,2L,2L,2L,2L,2L,2L,3L,3L,3L,3L,3L,3L,
3L,3L),
tp = c(10L,10L,10L,10L,20L,20L,
20L,20L,10L,10L,10L,10L,20L,20L,20L,20L,10L,10L,
10L,10L,20L,20L,20L,20L),
Methods = c("lmm","residualboot",
"clustboot","mbbboot","lmm","residualboot","clustboot",
"mbbboot","lmm","residualboot","clustboot","mbbboot",
"lmm","residualboot","clustboot","mbbboot","lmm",
"residualboot","clustboot","mbbboot","lmm","residualboot",
"clustboot","mbbboot"),
fixinterbias = c(-0.07069111,-0.08709062,
-0.13675904,-0.03077662,-0.2093937,-0.2092973,0.2344589,
-0.1650586,-0.08666544,-0.09681292,0.05795378,
-0.08564713,-0.015873476,-0.022712667,-0.090171359,
0.001930576,0.03720186,0.04073916,-0.08692844,0.04538355,
-0.09867106,-0.09874304,-0.08654507,-0.1161617),
fixslopebias = c(0.06225352,0.06467038,
0.06003106,0.05557157,-0.01036622,-0.01039492,-0.083628,
-0.01530608,0.02736118,0.02863767,0.04872466,0.02607667,
0.08056533,0.08076664,0.09773794,0.07819871,
-0.0703907,-0.07103784,-0.06005637,-0.07246422,0.0189303,
0.01863365,0.0145846,0.02057585)
)
And here is my code:
fixinter <- ggplot(xx, aes(x=sample, y=fixinterbias, shape=Methods, linetype=Methods)) +
geom_line(aes(color=Methods), size = 0.75) +
geom_hline(yintercept=0, linetype="dashed", color = "black") +
scale_shape_manual(values=c(0, 1, 2, 5)) +
scale_x_continuous(name="Sample size (n)", breaks = c(1, 2, 3), label = c(20, 50, 100)) +
scale_y_continuous(name="fix-effect intercept bias") +
geom_point(aes(color=Methods, shape = Methods),
stroke = 1.0, fill = "white") +
theme_classic()
fixinter + facet_grid(tp ~. )
You can use the "filled" version of each shape (use for example ggpubr::show_point_shapes() to see a list), so here 22, 21, 24 and 23.
fixinter <- ggplot(xx, aes(x=sample, y=fixinterbias, shape=Methods, linetype=Methods)) +
geom_line(aes(color=Methods), size = 0.75) +
geom_hline(yintercept=0, linetype="dashed", color = "black") +
scale_shape_manual(values=c(22, 21, 24, 23)) +
scale_x_continuous(name="Sample size (n)", breaks = c(1, 2, 3), label = c(20, 50, 100)) +
scale_y_continuous(name="fix-effect intercept bias") +
geom_point(aes(color=Methods, shape = Methods),
stroke = 1.0, fill = "white") +
theme_classic()
fixinter + facet_grid(tp ~. )

How to resolve problem with ggplot and ggsignif

I am trying to plot the differences in pairs. I found an example on this forum, but to this graph I would like to add the significance level information using the geom_signif function.
Unfortunately, I get the message back:
"Error in f (...):
Can only handle data with groups that are plotted on the x-axis "
Can someone help me fix this problem?
d <- data.frame(y = rnorm(20, 9, 2),
group = as.factor(rep(c('Post-FAP', 'Post-DEP'), each = 10)),
id = rep(1:10, 2))
ggplot(d, aes(y = y)) +
geom_boxplot(aes(x = rep(c(-2.5, 2.5), each = 10), group = group), fill = '#47E3FF') +
geom_point(aes(x = rep(c(-1, 1), each = 10)), shape = 21, size = 1.5, col = "black", fill = "grey") +
geom_line(aes(x = rep(c(-1, 1), each = 10), group = id)) +
#geom_signif(annotation = "p=0.05", y_position = 13, xmin = -2.5, xmax = 2.5, tip_length = .02) +
scale_x_continuous(breaks = c(-2.5, 2.5), labels = c("Post-FAP", "Post-DEP")) +
scale_y_continuous(minor_breaks = seq(5, 14, by =1),
breaks = seq(6, 14, by = 2), limits = c(5, 14),
guide = "axis_minor") +
theme_bw() +
theme(legend.position = "none", panel.grid = element_blank())
I think what you need to do is install ggh4x. It is an addon to ggplot2 that has some helpful tools, like properly adding ticks and minor ticks in your case. Once you load the R package then you should be good to go.
Edit:
The reason that you were getting that error was that you were not specifying group() for ggsignif
library(ggh4x)
library(ggplot2)
library(ggsignif)
ggplot(d, aes(y = y)) +
geom_boxplot(aes(x = rep(c(-2.5, 2.5), each = 10), group = group), fill = '#47E3FF') +
geom_point(aes(x = rep(c(-1, 1), each = 10)), shape = 21, size = 1.5, col = "black", fill = "grey") +
geom_line(aes(x = rep(c(-1, 1), each = 10), group = id)) +
geom_signif(d, mapping = aes(x=id, y=y,group=group),annotation = "p=0.05", y_position = 13, xmin = -2.5, xmax = 2.5, tip_length = .02) +
scale_x_continuous(breaks = c(-2.5, 2.5), labels = c("Post-FAP", "Post-DEP")) +
scale_y_continuous(minor_breaks = seq(5, 14, by =1),
breaks = seq(5, 14, by = 2), limits = c(5, 14),
guide = "axis_minor") +
theme_bw() +
theme(legend.position = "none", panel.grid = element_blank())
There is a thread here on the error message you posted, saying that all the information on aes (x and y) need to be accessible by the subfunction, i.e. geom_signif.
Using ggplot(d, x=aes(as.numeric(group), y=y, group = group)) worked for me.
Interestingly, ggplot(d, x=aes(rep(c(-2.5, 2.5), each = 10), y=y, group = group)) , did not return an error, but also did not show the geom_signif annotation.

How to define individual legend elements in ggplot2?

I need to create sensible legends for this chart.
I am using R version 3.5.2 and ggplot2 version 3.1.0.9000.
What I have so far:
as.data.frame(list(
name = c('alice', 'bob', 'charlie'),
y = c(2, 3, 3.5),
y_min = c(1, 1.5, 1.25),
y_max = c(4, 3.5, 7),
asterisk = c(6, 3.75, 9)
)
) %>%
ggplot(aes(y = y, x = name)) +
geom_point(aes(color = 'main', shape = 'main'), size = 4) +
geom_point(aes(y = asterisk, color = 'asterisk', shape = 'asterisk'), size = 6) +
scale_color_manual(values = list('main' = 'black', 'asterisk' = 'red')) +
scale_shape_manual(values = list('main' = 16, 'asterisk' = 42)) +
geom_segment(aes(y = y_min, yend = y_max, xend = name)) +
coord_flip()
I am hoping to get the legend to show just a large-black-dot and a small-red-asterisk, preferably under one header. There is no large-red-dot or small-black-asterisk, and it is confusing that those symbols appear in the legend.
You need to give both legends the same name so they become one
ggplot(dat, aes(y=y, x=name)) +
geom_point(aes(color='main',
shape='main'), size=4) +
geom_point(aes(y=asterisk,
color='asterisk',
shape='asterisk'), size=6) +
scale_color_manual(name = "legend_title", # changed name here
values=c('main'='black', 'asterisk'='red')) +
scale_shape_manual(name = "legend_title", # and here
values=c('main'=16, 'asterisk'=42)) +
geom_segment(aes(y=y_min, yend=y_max, xend=name)) +
coord_flip()
data
dat <- data.frame(
name = c('alice', 'bob', 'charlie'),
y = c(2, 3, 3.5),
y_min = c(1, 1.5, 1.25),
y_max = c(4, 3.5, 7),
asterisk = c(6, 3.75, 9), stringsAsFactors = FALSE)

Resources