Reputation: 955
I have the following ggplot2
code that plots multiple polynomial fits with various degrees:
library(ggplot2)
set.seed(1234)
n = 400
x = rnorm(n, sd=0.4)
y = -x + 2*x^2 - 3*x^3 + rnorm(n,sd=0.75)
df = data.frame(x=x,y=y)
deg = c(1,2,3,10)
cols = c("red","green","blue","orange")
ggplot(df, aes(x=x,y=y)) +
geom_point() +
geom_smooth(method = "lm", formula= y~poly(x,deg[1]), se=F, col=cols[1]) +
geom_smooth(method = "lm", formula= y~poly(x,deg[2]), se=F, col=cols[2]) +
geom_smooth(method = "lm", formula= y~poly(x,deg[3]), se=F, col=cols[3]) +
geom_smooth(method = "lm", formula= y~poly(x,deg[4]), se=F, col=cols[4])
I would like to avoid repeating the geom_smooth
line for every degree. But I can't figure out how to get geom_smooth
to understand a dynamic degree passed through a variable. Is there a more elegant solution to the above? It would be nice to also automatically change the colors without the need to explicitly pass the cols
vector. (Default color scheme is fine).
I have tried to use as.formula(paste0("y~poly(x,",deg[i],")"))
through a loop without much luck (and loops don't seem to be the right approach with ggplot
.)
Upvotes: 3
Views: 1764
Reputation: 93811
You can add a list of plot elements to a ggplot, so you could use map
to create a list of four geom_smooth
calls, one for each degree in deg
.
library(tidyverse)
ggplot(df, aes(x=x,y=y)) +
geom_point() +
map(1:length(deg),
~geom_smooth(method="lm", formula=y~poly(x, deg[.x]), se=F, col=cols[.x]))
You can also add a legend if you wish. For example:
ggplot(df, aes(x=x,y=y)) +
geom_point(colour="grey60") +
map(1:length(deg),
~geom_smooth(method="lm", formula=y~poly(x, deg[.x]), se=F,
aes(color=factor(deg[.x])))) +
scale_colour_manual(name="Degree", breaks=deg, values=set_names(cols, deg)) +
theme_bw() +
theme(legend.text.align=1)
If you're happy with the default colours, change the scale_colour_manual
line to:
scale_colour_discrete(name="Degree", breaks=deg) +
Upvotes: 6