Why my codes is unable to add legend to figure in ggplot2 - r

I want to add some legend to this figure.
There are one set of scatter points and two lines.
Below is my codes.
rm(list = ls())
n=500
set.seed(100)
x1=seq(from=-3,to=3,length.out = n)
a=rnorm(n,mean=0,sd=0.2)
z=1+2*x1+a
p=1/(1+exp(-z))
y=(p>=(runif(n,min=0.4,max=0.6)))*1
X=data.frame(x1=x1,y=y)
K=glm(formula=y~x1,family=binomial(link="logit"),data=X)
p_fit=1/(1+exp(-(K$coefficients[1]+K$coefficients[2]*x1)))
ggplot()+ xlab("x1")+ ylab("y")+facet_grid()+
geom_point(data=data.frame(x1,y), aes(x=x1, y=y),size=4)+
geom_line(data=data.frame(x1,p), aes(x=x1, y=p),size=1.2,col="blue")+
geom_line(data=data.frame(x1,p_fit), aes(x=x1, y=p_fit),size=1.5,col="red")+
theme(legend.position =c(0.8,0.5))

In ggplot legends appear when you map a variable or a constant to an aesthetic. In your case, try as follow.
ggplot() +
geom_point(data = data.frame(x1, y), aes(x = x1, y = y), size = 3, alpha = 0.5)+
geom_line(data = data.frame(x1, p),
aes(x = x1, y = p, color = 'p'),
size = 1.2) +
geom_line(data = data.frame(x1, p_fit),
aes(x = x1, y = p_fit, color = "p_fit"), size = 1.5) +
xlab("x1") +
ylab("y")+
theme(legend.position = c(0.8, 0.5)) +
scale_color_manual(values = c("blue", "red"))

Related

Pass changed geom from object to other ggplot

I first make a plot
df <- data.frame(x = c(1:40, rep(1:20, 3), 15:40))
p <- ggplot(df, aes(x=x, y = x)) +
stat_density2d(aes(fill='red',alpha=..level..),geom='polygon', show.legend = F)
Then I want to change the geom_density values and use these in another plot.
# build plot
q <- ggplot_build(p)
# Change density
dens <- q$data[[1]]
dens$y <- dens$y - dens$x
Build the other plot using the changed densities, something like this:
# Built another plot
ggplot(df, aes(x=x, y =1)) +
geom_point(alpha = 0.3) +
geom_density2d(dens)
This does not work however is there a way of doing this?
EDIT: doing it when there are multiple groups:
df <- data.frame(x = c(1:40, rep(1:20, 3), 15:40), group = c(rep('A',40), rep('B',60), rep('C',26)))
p <- ggplot(df, aes(x=x, y = x)) +
stat_density2d(aes(fill=group,alpha=..level..),geom='polygon', show.legend = F)
q <- ggplot_build(p)
dens <- q$data[[1]]
dens$y <- dens$y - dens$x
ggplot(df, aes(x=x, y =1)) +
geom_point(aes(col = group), alpha = 0.3) +
geom_polygon(data = dens, aes(x, y, fill = fill, group = piece, alpha = alpha)) +
scale_alpha_identity() +
guides(fill = F, alpha = F)
Results when applied to my own dataset
Although this is exactly what I'm looking for the fill colors seem not to correspond to the initial colors (linked to A, B and C):
Like this? It is possible to plot a transformation of the shapes plotted by geom_density. But that's not quite the same as manipulating the underlying density...
ggplot(df, aes(x=x, y =1)) +
geom_point(alpha = 0.3) +
geom_polygon(data = dens, aes(x, y, fill = fill, group = piece, alpha = alpha)) +
scale_alpha_identity() +
guides(fill = F, alpha = F)
Edit - OP now has multiple groups. We can plot those with the code below, which produces an artistic plot of questionably utility. It does what you propose, but I would suggest it would be more fruitful to transform the underlying data and summarize that, if you are looking for representative output.
ggplot(df, aes(x=x, y =1)) +
geom_point(aes(col = group), alpha = 0.3) +
geom_polygon(data = dens, aes(x, y, fill = group, group = piece, alpha = alpha)) +
scale_alpha_identity() +
guides(fill = F, alpha = F) +
theme_minimal()

Plot one line with a solid color and a second line with a gradient

I would like to plot two lines on one chart, one with a color gradient and the other a solid color. I can add individual lines and a gradient:
x <- seq(1, 100, 1)
y <- rnorm(100, 50, 15)
z <- rnorm(100, 30, 5)
df <- data.frame(x,y,z)
library(ggplot2)
ggplot(df, aes(x = x, y = y, color = x)) + geom_line() +
scale_color_gradient(low = "blue", high = "red") +
geom_line(data = df, aes(x = x, y = z, color = x))
But changing the color throws an error:
> ggplot(df, aes(x = x, y = y, color = ..y..)) + geom_line() +
+ scale_color_gradient(low = "blue", high = "red") +
+ geom_line(aes(x = x, y = z, color = "yellow"))
Error: Discrete value supplied to continuous scale
I'm hoping to add labels, but that may be to complex for this...
Simplest way is to specify color for a solid line outside of aes:
library(ggplot2)
ggplot(df, aes(x, y, color = x)) +
geom_line() +
# No need to respecify data or x at it's defined in main ggplot call
geom_line(aes(y = z), color = "yellow") +
scale_color_gradient(low = "blue", high = "red")

Add regression line legend to geom_abline

I've coded this:
ggplot() +
geom_point(mapping = aes(x = X, y = y)) +
geom_abline(intercept = -0.9930872, slope = 0.4866284, colour = "red") +
geom_abline(intercept = -1, slope = 0.5, colour = "blue")
but cannot seem to get a working legend for my least square and populuation regression line. I've tried various stack overflow answers but nothing seems to give me what I need.
Add a legend to a ggplot2 scatter plot including additional lines
This looked like the best answer, but I can't get it to work!
Any suggestions?
set.seed(1234)
X <- rnorm(20,sd=2.5)
y <- -1+0.5*X+rnorm(20, sd=0.4)
library(ggplot2)
ggplot() +
geom_point(mapping = aes(x = X, y = y)) +
geom_abline(aes(intercept = -0.9930872, slope = 0.4866284, colour = "line1"), lwd=1) +
geom_abline(aes(intercept = -1, slope = 0.5, colour = "line2"), lwd=1) +
scale_colour_manual(values=c("line1"="red","line2"="blue"))
With slight modification your code works just fine:
ggplot() +
geom_point(mapping = aes(x = X, y = y)) +
geom_abline(aes(colour = "line_1", intercept = -0.9930872, slope = 0.4866284)) +
geom_abline(aes(colour = "line_2", intercept = -1, slope = 0.5)) +
scale_colour_manual(name = "lines", values = c("red", "blue")) +
theme(legend.position = "bottom")
Added legend position in case if you want to change that aswell.

Labeling two contours with direct.labels

I'm trying to compare two scalar fields and want to draw them in the same plot using contours labeling their values with directlabels.
The thing is, I'm not able to use two direct labels in the same plot.
Example:
library(ggplot2)
library(data.table)
library(directlabels)
grid <- expand.grid(lon = seq(0, 360, by = 2), lat = seq(-90, 0, by = 2))
grid$z <- with(grid, cos(lat*pi/180))
grid$z2 <- with(grid, sin(lat*pi/180))
grid.long <- melt(grid, id.vars = c("lon", "lat"))
# Manually adding two geom_dl's
ggplot(grid, aes(lon, lat)) +
geom_contour(aes(z = z), color = "black") +
geom_contour(aes(z = z2), color = "red") +
geom_dl(aes(z = z2, label = ..level..), stat = "contour", method = "top.pieces", color = "red") +
geom_dl(aes(z = z, label = ..level..), stat = "contour", method = "top.pieces", color = "black")
Only one variable is labeled.
Another way:
ggplot(grid.long, aes(lon, lat)) +
geom_contour(aes(z = value, color = variable)) +
geom_dl(aes(z = value, label = ..level.., color = variable),
stat = "contour", method = "top.pieces")
Any solution?
Thanks!
One solution is to provide different method= argument for the second geom_dl() call.
ggplot(grid, aes(lon, lat)) +
geom_contour(aes(z = z), color = "black") +
geom_contour(aes(z = z2), color = "red") +
geom_dl(aes(z = z2, label = ..level..), stat = "contour", method = "top.pieces", color = "red") +
geom_dl(aes(z = z, label = ..level..), stat = "contour", method = "bottom.pieces", color = "black")

How to add a custom legend in ggplot2 in R

I want to plot a data set where the size of the points are proportional to the x-variable and have a regression line with a 95% prediction interval. The "sample" code I have written is as follows:
# Create random data and run regression
x <- rnorm(40)
y <- 0.5 * x + rnorm(40)
plot.dta <- data.frame(y, x)
mod <- lm(y ~ x, data = plot.dta)
# Create values for prediction interval
x.new <- data.frame(x = seq(-2.5, 2.5, length = 1000))
pred <- predict(mod,, newdata = x.new, interval = "prediction")
pred <- data.frame(cbind(x.new, pred))
# plot the data w/ regression line and prediction interval
p <- ggplot(pred, aes(x = x, y = upr)) +
geom_line(aes(y = lwr), color = "#666666", linetype = "dashed") +
geom_line(aes(y = upr), color = "#666666", linetype = "dashed") +
geom_line(aes(y = fit)) +
geom_point(data = plot.dta, aes(y = y, size = x))
p
This produces the following plot:
Obviously, the legend is not too helpful here. I would like to have one entry in the legend for the points, say, labeled "data", one grey, dashed line labeled "95% PI" and one entry with a black line labeled "Regression line."
As Hack-R alluded in the provided link, you can set the breaks and labels for scale_size() to make that legend more meaningful.
You can also construct a legend for all your geom_line() calls by adding linetype into your aes() and use a scale_linetype_manual() to set the values, breaks and labels.
ggplot(pred, aes(x = x, y = upr)) +
geom_line(aes(y = lwr, linetype = "dashed"), color = "#666666") +
geom_line(aes(y = upr, linetype = "dashed"), color = "#666666") +
geom_line(aes(y = fit, linetype = "solid")) +
geom_point(data = plot.dta, aes(y = y, size = x)) +
scale_size(labels = c("Eensy-weensy", "Teeny", "Small", "Medium", "Large")) +
scale_linetype_manual(values = c("dashed" = 2, "solid" = 1), labels = c("95% PI", "Regression Line"))

Resources