'How to hold slope constant with geom_smooth drawing trend lines for groups?

I cannot find an obvious solution in ggplot2 for a common, trivial statistics problem. I want geom_smooth(method = "lm") to hold the slope constant between groups in the color aesthetic.

The naive model I begin with is lm(Sepal.Width ~ Sepal.Length, data = iris). Graphing this in ggplot2:

library(ggplot2)
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width) +
    geom_point() + 
    geom_smooth(method = "lm")

To add a control for Species, I'd like to test lm(Sepal.Width ~ Sepal.Length + factor(Species), data = iris, which holds the slope constant between different species (the model is fitted with one coefficient for sepal length, with only constants varying between species). I'd also like to test lm(Sepal.Width ~ Sepal.Length*Species, data = iris), which allows the association between sepal length and sepal width to vary between species.

The second model is trivial to plot:

library(ggplot2)
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species) + 
    geom_point() + 
    geom_smooth(method = "lm")

This plot allows the slopes to vary. Is there a way to prevent the slopes from varying?



Solution 1:[1]

Your desired result requires some manual work, i.e. estimate the model outside of ggplot and add a column with predicted values to your dataframe which could then be plotted using geom_line. Same for the other models you want to test:

library(ggplot2)

iris2 <- iris
iris2$fit <- predict(lm(Sepal.Width ~ Sepal.Length + factor(Species), data = iris2))

ggplot(iris2, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) + 
  geom_point() + 
  geom_line(aes(y = fit))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 stefan