polynomial regression plot predicted value [closed]

I made a plot of a polynomial regression model with predicted y values on the y-axis and x on the x-axis. With the original data also on the plot, I can visualize my model. However, with this particular dataset, I can see 2 lines for the predicted values. See below:

Here's the code for my model:

fit <- lm(y~ poly(x2,2), data = data1)
pred1 <- predict(fit, data = data1)
plot(x2, y, xlab = "x", ylab = "y")
lines(x2, pred1, lwd = .1, col = "blue")


Did I do something wrong here? I would imagine it will be a single curve line for the predictions.

closed as off-topic by Roland, mdewey, kjetil b halvorsen, gung♦, COOLSerdashMar 16 '17 at 18:01

This question appears to be off-topic. The users who voted to close gave this specific reason:

• "This question appears to be off-topic because EITHER it is not about statistics, machine learning, data analysis, data mining, or data visualization, OR it focuses on programming, debugging, or performing routine operations within a statistical computing platform. If the latter, you could try the support links we maintain." – Roland, mdewey, kjetil b halvorsen, gung, COOLSerdash
If this question can be reworded to fit the rules in the help center, please edit the question.

• What happens when you replace your second line of code with the following? pred1 <- predict(fit, data = data1, interval="none") – Anna SdTC Mar 15 '17 at 1:40
• I still see 2 blue lines. My dataset is consisted of uniformly distributed x's and about 40 values of y's – ajax2000 Mar 15 '17 at 1:50
• This is a duplicate of several questions at Stack Overflow. – Roland Mar 15 '17 at 7:55

This issue is arising from your call to the predict function. I think it must be something about how predict() handles models with polynomial terms --- I'm not quite sure why it's grouping it into multiple lines, but I do know how you can fix it.

If you specify newdata for the predict function instead of relying on the original data used for the fit, you should get a curve like you were expecting. Here's an example, using the mtcars data. First, I'll replicate your problem.

fit1 <- lm(mpg ~ poly(qsec, 2), data = mtcars)
pred <- predict(fit1)
plot(mpg ~ qsec, data = mtcars)
lines(mtcars$qsec, y=pred, col = "blue")  This gives the multiple line result, like you found: Instead, create a new dataframe to feed predict. Here, I'm using the full range of the predictor variable, stepping in a sequence from its min to its max by .01 newdata <- data.frame(qsec=seq(min(mtcars$qsec), max(mtcars$qsec), .01)) newdata$pred1 <- predict(fit1, newdata)
plot(mpg ~ qsec, data = mtcars)
lines(newdata$qsec, newdata$pred1, col = "red")


Alternatively, you can use ggplot2 for the plotting instead, where you won't face this strange issue.

ggplot(mtcars, aes(y=mpg, x=qsec)) +
geom_point(alpha = .5) +
stat_smooth(method = "lm", formula = y ~ poly(x,2))


One other random note on the poly() function:

Many people don't realize that its defaults produce polynomial trend contrasts, rather than polynomial terms of a continuous variable for polynomial regression. You'll notice the difference if you examine the regression coefficients from your model. Compare them to a model where you build the polynomial terms by hand (i.e. actually create a squared version of your x2 variable to add as a predictor to the model along with x2) and you'll see.

If you want polynomial terms instead of contrast codes, you need to use raw = TRUE when you call poly(). See ?poly for more information.

• The problem is just the sorting of x values: Use lines(sort(mtcars$qsec), y=pred[order(mtcars$qsec)], col = "blue") in your first example. – Roland Mar 15 '17 at 7:53

I believe you should use lines(), but stick with the predicted values alone:

data(mtcars)
with(mtcars, plot(mpg,wt))
lines(predict(lm(wt ~ mpg, data = mtcars)))


A ggplot2 solution:

library(ggplot2)
ggplot(data = mtcars, aes(x = mpg, y = wt))+
+ geom_point()+
+ geom_smooth(method = 'lm')


• This doesn't address the issues for polynomial regression. – Rose Hartman Mar 15 '17 at 3:53