How to add a second legend using different `geom_line`? - r

I am plotting the relationship between two variables (X and Y) for different individuals (IDs). This relationship is shown both with the real values (geom_point) and with lines which represent the prediction of the relationship between the variables for different individuals Linear Mixed Effect Models (LME). On top of that, the linear relationship between the two variables and for the different individuals is done using three levels of a second quantitative predictor (Z).
Thus, what I do is to use geom_point() for showing the relationship between raw values of X and Y. Then, I use three geom_line() for three LME with different levels of Z. Thus, each geom_line() draws the six lines for the six IDs for a fixed Z. So, since I have 3 Z levels and I have 3 geom_line(), I have 18 lines.
I tried this (note: code is simplified):
Plot_legend <- ggplot(df, aes(x=X, y=Y, colour=ID)) +
geom_point(size=1.5,alpha=0.2) +
geom_line(aes(y=predict(model,df.Z_low), group=ID, linetype = c("1")), size=1.5, alpha=0.6, color = line_colors[3]) +
geom_line(aes(y=predict(model,df.Z_medium), group=ID, linetype = c("2")), size=1.5, alpha=0.6, color = line_colors[2]) +
geom_line(aes(y=predict(model,df.Z_high), group=ID, linetype = c("3")), size=1.5, alpha=0.6, color = line_colors[1]) +
geom_abline(aes(slope=1,intercept=0),linetype="dashed",color="grey52",size=1.5) +
theme_bw() +
theme(legend.text=element_text(size=18),
legend.title = element_text(size=19, face = "bold",hjust = 0.5),
legend.key=element_blank(),
legend.background = element_rect(colour = 'black', fill = 'white', size = 1, linetype='solid')) +
guides(color=guide_legend(override.aes=list(fill=NA)))
However, as you can see, the legend for the three geom_line() is not what I desire. I would like to appear as title Z instead of c("10th"). Also, the colours of the legend for the three geom_line() do not correspond with the true colours for the different geom_line(), and some lines are dashed.
Does anyone know how to solve this?
Plot using Duck's advice

Try this approach. As no data was shared I can test it but it can address in right path:
library(ggplot2)
#Code
Plot_legend <- ggplot(df, aes(x=X, y=Y, colour=ID)) +
geom_point(size=1.5,alpha=0.2) +
geom_line(aes(y=predict(model,df.Z_low), group=ID, linetype = c("1")),
size=1.5, alpha=0.6, color = line_colors[3]) +
geom_line(aes(y=predict(model,df.Z_medium), group=ID, linetype = c("2")),
size=1.5, alpha=0.6, color = line_colors[2]) +
geom_line(aes(y=predict(model,df.Z_high), group=ID, linetype = c("3")),
size=1.5, alpha=0.6, color = line_colors[1]) +
geom_abline(aes(slope=1,intercept=0),linetype="dashed",color="grey52",size=1.5) +
theme_bw() +
scale_linetype_manual(values=c('solid','solid','solid'))+
scale_color_manual(values=c(line_colors[3],line_colors[2],line_colors[1]))+
labs(linetype='Z')
theme(legend.text=element_text(size=18),
legend.title = element_text(size=19, face = "bold",hjust = 0.5),
legend.key=element_blank(),
legend.background = element_rect(colour = 'black', fill = 'white', size = 1, linetype='solid')) +
guides(color=guide_legend(override.aes=list(fill=NA)))

I used next code finally:
Plot_legend <- ggplot(df, aes(x=X, y=Y, colour=ID)) +
geom_point(size=1.5,alpha=0.2) +
geom_abline(aes(slope=1,intercept=0),linetype="dashed",color="grey52",size=1.5) +
theme_bw() +
theme(legend.text=element_text(size=18),
legend.title = element_text(size=19, face = "bold",hjust = 0.5),
legend.key=element_blank(),
legend.background = element_rect(colour = 'black', fill = 'white', size = 1, linetype='solid')) +
guides(color=guide_legend(override.aes=list(fill=NA)))
Plot_legend
Plot_legend_2 <- Plot_legend +
geom_line(aes(y=predict(model,df.Z_low), group=ID, linetype = "m1"), size=1.5, alpha=0.6, color = line_colors[3]) +
geom_line(aes(y=predict(model,df.Z_medium), group=ID, linetype ="m2"), size=1.5, alpha=0.6, color = line_colors[2]) +
geom_line(aes(y=predict(model,df.Z_high), group=ID, linetype ="m3"), size=1.5, alpha=0.6, color = line_colors[1]) +
scale_linetype_manual(values = c(m1 = "solid", m2 = "solid", m3 = "solid"),labels = c(m1 = "1", m2 = "2", m3 = "3")) +
labs(color = "ID", linetype = expression(Z)) +
guides(linetype = guide_legend(override.aes = list(color = line_colors)))
Plot_legend_2

Related

How to draw an inclined line and parallelly put the text on it in ggplot?

Now, I'm making some hypothesis graph and I made this graph.
x<- c(1,2,3,4,5,6,7,8,9,10,11)
y<- c(100,90,80,70,60,50,40,30,20,10,1)
a<- c(1,2,3,4,5,6,7,8,9,10)
b<- c(1,4,9,16,25,36,49,64,81,100)
dataA<- data.frame (x,y)
dataB<- data.frame (a,b)
geom_line(data=dataA, aes(x=x, y=y), col="Dark red", size=1) +
geom_line(data=dataB, aes(x=a, y=b), col="Dark blue", size=1) +
scale_x_continuous(breaks = seq(0,12,1), limits = c(0,12)) +
scale_y_continuous(breaks = seq(0,120,10), limits = c(0,120)) +
geom_hline(yintercept=70, linetype="dashed", color = "Black", size=1) +
geom_hline(yintercept=50, linetype="dashed", color = "Black", size=1) +
#geom_text(aes(fontface=6), x=11, y=110, label=paste("% distal\n","grains"), size=6, col="Dark blue") +
geom_text(aes(fontface=6), x=10, y=75, label="AGW (90th percentile)", size=5, col="Black") +
geom_text(aes(fontface=6), x=10, y=55, label="AGW (10th percentile)", size=5, col="Black") +
xlab(bquote('x ('~m^2*')')) +
ylab(bquote('y (mg '~grain^-1*')')) +
theme(axis.title = element_text (face = "plain", size = 18, color = "black"),
axis.text.x = element_blank(), #element_blank()) element_text(size= 14)
axis.text.y = element_blank(),
axis.ticks.x = element_blank(),
axis.ticks.y = element_blank(),
axis.line = element_line(size = 0.5, colour = "black"))+
windows(width=5.5, height=5)
As an alternatives, I need to present such as below graph, but I don't know how to draw an inclined line, starting a specific point of y-axis. Also, I would like to add a text on the line in a parallel position. Could you tell me how I can do this?
Many thanks!!
Here is a concrete example based on #Waldi 's comment:
library(ggplot2)
# Change line to what you want
line <- data.frame(x = c(10,30), y = c(300,50))
line = lm(formula = line$y ~ line$x)$coefficients
# ratio required for unequal axis scales
ratio <- 1/15
# get angle of the line
angle <- atan(line[2] * ratio) * 180 / pi
# plot it
ggplot(mtcars, aes(x = mpg, y = hp)) +
geom_point() +
geom_abline(slope = line[2], intercept = line[1], color = "blue") +
coord_equal(ratio = ratio) +
annotate(
geom = "text",
x = 20,
y = 20 * line[2] + line[1],
label = "My Line",
color = "blue",
angle = angle,
vjust = -1 # offset so text isn't directly on the line
)

How to remove x and y axis labels from a boxplot in R?

I have been writing some code for a class, and I have got stuck in how to remove the x and y labels from the boxplot. I am planning to place it within a 1st graph, so they are redundant.
If anyone also knows how to add a line at 0 to my line graph, that would be amazing aswell!
Code:
#load data up
library(readxl)
TempData <- read_excel("R Data/TempData.xlsx")
View(TempData)
#initiliase relevant packages #ggplot2 for creating data visulation and viridis to allow for colour gradients
library(ggplot2)
library(viridis)
#plot line graph
g1 <- ggplot(TempData, aes(x = Year, y = GAT, color = GAT)) +
geom_line(size = 1.5) +
geom_smooth(method=loess, se=TRUE, col = "black") +
scale_colour_gradient2(low = "green", mid = "yellow" , high = "red", midpoint=median(TempData$GAT)) +
labs(title = "Global Average Temperature", subtitle = "From 1850 to 2018") +
xlab("Year") + ylab ("Average Temperature") +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 16)) +
theme(plot.subtitle = element_text(face = "italic", hjust = 0.5, size = 10, colour = "Orange")) +
theme_light()
plot(g1)
#plot boxplot
g2 <- ggplot(TempData, aes(x="Year", y=TempData$GAT)) + geom_boxplot(outlier.colour = "red", outlier.fill = "red",outlier.shape = 21, outlier.size = 1)
labs(x=" ", y=" ") +
stat_summary(fun.y = mean, geom = "point", size = 2.5, colour = "orange") +
theme_light()
plot(g2)
#arrange two graphs to boxplot sits in top corner of line graph
g1 + annotation_custom(ggplotGrob(g2), xmin = 1840, xmax = 1930, ymin = 0.20, ymax = 0.88)
you could use theme in the following way:
... + theme(axis.title.x=element_blank(), axis.title.y=element_blank())
This will remove the x,y labels of the plot

Multiplot facet line plot in ggplot2 with two Y axes - adding points and changing line colours

I am preparing a multiplot for with two y axes for Inc and Ratio.
I distinguished each plot with different colours to represent three regions.
There are three items I am not successful at:
I do have now, two lines with the same colour in each plot. I would like to change one of them to be dashed (Ratio one).
I need to add SE bars to Inc line (from Inc column)
I would like to add geom_points() so there are also points at the nodes where lines are connecting, only for aesthetic reasons.
This is as far as I get:
df <- data.frame(c(2009,2009,2009,2009,2010,2010,2010,2010,2011,2011,2011,2011,
2012,2012,2012,2012,2013,2013,2013,2013),
c("N","S","W","W","N","S","W","W","N","S","W","W","N","S","W","W",
"N","S","W","W"),
c("Luo","Aka","Opo","Mya","Luo","Aka","Opo","Mya",
"Luo","Aka","Opo","Mya","Luo","Aka","Opo","Mya",
"Luo","Aka","Opo","Mya"),
runif(20,0,1),runif(20,0,1),
runif(20,0,0.1))
colnames(df) <- c("Year","Region","District","Inc","Ratio","Inc_SE")
# Order of drawing in facet
df$District<- factor(df$District,
levels = c("Opo",
"Mya",
"Luo",
"Aka"))
p <- ggplot(data=df, aes(x = Year))
p <- p + geom_line(aes(y = Inc))
p <- ggplot(df, aes(x = Year, y=df$Inc))
p <- p + geom_line(aes(y = Inc))
p <- ggplot(df, aes(x = Year))
p <- p + geom_line(aes(y = Inc, colour = Region))
p <- p + theme_bw()+
theme(plot.title = element_text(hjust = 1))+
theme(legend.position="none")+
theme(axis.title.x = element_text(face ="bold", colour="black", size=11),
axis.text.x = element_text(angle=90, vjust=0.5, size=7, family = "serif"),
axis.title.y = element_text(face = "bold", colour = "black", size=10))
# adding Ratio
p <- p + geom_line(aes(y = Ratio, colour = Region,linetype = "dashed")) # here dashed is not recognised by R
# now adding the secondary axis
p <- p + scale_y_continuous(sec.axis = sec_axis(~.*1, name = "Ratio"))
p <- p + scale_colour_manual(values = c("blue", "red","black"))
p <- p +
theme_bw()+
theme(plot.title = element_text(hjust = 1))+
theme(legend.position="none")+
theme(axis.title.x = element_text(face ="bold", colour="black", size=11),
axis.text.x = element_text(angle=90, vjust=0.5, size=9, family = "serif"),
axis.title.y = element_text(face = "bold", colour = "black", size=10))
# Breaking down to separate graphs
p_facet = p + facet_wrap(~ df$District,
ncol = 2)
p_facet
You can try a tidyverse. The trick is to transform the data from wide to long (here I used gather). then you can easily add points, lines and Inc_SE as ribbon.
library(tidyverse)
df %>%
gather(k,v, -Year, -Region, -District, -Inc_SE) %>%
ggplot(aes(Year, v, group = k, color=Region, linetype=k)) +
geom_ribbon(data=. %>% filter( k == "Inc"),
aes(ymin=v-Inc_SE, ymax=v+Inc_SE),
alpha=0.2,color=NA,
show.legend = F) +
geom_line() +
geom_point(show.legend = F)+
scale_y_continuous(sec.axis = sec_axis(~.*1, name = "Ratio"))+
facet_wrap(~ District) +
labs(y="Inc") +
theme_bw() +
theme(legend.position = "bottom")

Add custom legend to a ggplot

I made a scatter plot and then added a regression line. I'm new in ggplot2 and I didn't understand so well how to add a legend. I want a circle like the scater plot saying "data", and a line saying "regression". How can I do this?
library(ggplot2)
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),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 12))
And I want something like:
Custom legends can be tricky to achieve in ggplot as the system is heavily based around "mapping" your data to a scale and then using that to create the legend. For custom legends, you can use an aes() call that manually sets the label you want in the legend, like:
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),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 12))

Adding manual legend in ggplot

I've looked through prior similar questions and (I think) have done everything that's been recommended in them. Still not getting the output I want.
I have a bunch of distributions, which I'm displaying in facetted graphs. I then draw vertical lines through them, which represent different interventions.
I'm trying to display a legend that contains both the fill color of the distributions as well as the line color of those extra lines. As far as I can tell, I'm doing everything right (setting the color command within aes(), using scale_colour_manual() to define the legend, etc). I'm still only getting the legend for the fill colors.
Here's my code:
ggplot(modCosts, aes(x=cost)) + geom_density(aes(fill=group)) + theme_bw() +
facet_wrap(~ country, scales="free") + scale_x_continuous(label = dollar) +
scale_fill_brewer(palette = "RdGy", name = "Income group", labels = c("HIC" = "High income", "UMIC" = "Upper-middle income", "LIC" = "Low income")) +
labs(y = "Density", x = "Cost", title = "Medical costs of surgery\nActual vs. modeled") +
geom_vline(data = surgCosts, aes(xintercept = CS.tert.lo, color = "red4")) +
geom_vline(data = surgCosts, aes(xintercept = CS.tert.hi, color = "red4")) +
geom_vline(data = surgCosts, aes(xintercept = CS.prim.lo, color = "red4"), lty = "dashed") +
geom_vline(data = surgCosts, aes(xintercept = CS.prim.hi, color = "red4"), lty = "dashed") +
geom_vline(data = surgCosts, aes(xintercept = Lap.tert.lo, color = "deepskyblue")) +
geom_vline(data = surgCosts, aes(xintercept = Lap.tert.hi, color = "deepskyblue")) +
geom_vline(data = surgCosts, aes(xintercept = Lap.prim.lo, color = "deepskyblue"), lty = "dashed") +
geom_vline(data = surgCosts, aes(xintercept = Lap.prim.hi, color = "deepskyblue"), lty = "dashed") +
geom_vline(data = surgCosts, aes(xintercept = Fx.tert.lo, color = "yellowgreen")) +
geom_vline(data = surgCosts, aes(xintercept = Fx.tert.hi, color = "yellowgreen")) +
scale_color_manual(name = "Reported cost", values = c("red4" = "red4", "deepskyblue" = "deepskyblue", "yellowgreen" = "yellowgreen"),
labels = c("Int1", "Int2", "Int3")) +
theme(axis.ticks = element_blank(), axis.text.y = element_blank(), legend.position = "right")
And here's the output I'm getting:
Any help would be greatly appreciated!
There's a show_guide=... argument to geom_vline(...) (and _hline and _abline) which defaults to FALSE. Evidently the view was that most of the time you would not want the line colors to show up in a legend. Here's an example.
df <- mtcars
library(ggplot2)
ggp <- ggplot(df, aes(x=wt, y=mpg, fill=factor(cyl))) +
geom_point(shape=21, size=5)+
geom_vline(data=data.frame(x=3),aes(xintercept=x, color="red"), show_guide=TRUE)+
geom_vline(data=data.frame(x=4),aes(xintercept=x, color="green"), show_guide=TRUE)+
geom_vline(data=data.frame(x=5),aes(xintercept=x, color="blue"), show_guide=TRUE)
ggp +scale_color_manual("Line.Color", values=c(red="red",green="green",blue="blue"),
labels=paste0("Int",1:3))
BTW a better way to specify the scale if you insist on using color names is this:
ggp +scale_color_identity("Line.Color", labels=paste0("Int",1:3), guide="legend")
which produces the identical plot above.

Resources