I am trying to plot a scatterplot from mtcars of: hp ~ mpg and for each point (x,y) show how many cylinders (cyl) by different colors.
I tried to use the function ScatterPlot , but it's not recognized without adding the 'car' package.
So I tried :
plot(mtcars$mpg ~ mtcars$hp , data=mtcars, xlab="HP", ylab="Hwy.MPG")
How can I add number of cylinders for each point of this graph? (with different colors)
I'm going to assume you're using mtcars from datasets.
The simplest way to add colour is to just add a colargument:
plot(mpg ~ hp , data=mtcars, col=cyl, xlab="HP", ylab="Hwy.MPG")
If you want custom colours, you can use the palettefunction:
palette(c("red", "blue", "green"))
plot(mpg ~ hp , data=mtcars, col=cyl, xlab="HP", ylab="Hwy.MPG")
Here's an example in lattice It's a little more "Oo-Lala", and fairly straightforward.
library(lattice)
xyplot(mpg ~ hp, data = mtcars, groups = cyl, pch = 19,
xlab = "HP", ylab = "Hwy.MPG", auto.key = list(columns = 3))
And to complete the picture, here's the ggplot example
library(ggplot2)
ggplot(mtcars, aes(x = hp, y = mpg)) + geom_point(aes(color = factor(cyl)), size = 4)
Related
I want to graph an interaction effect between two variables with one outcome in R. While I can successfully produce a graph using sjPlot:plot_model(), the interaction plot does not resize when I adjust the x-axis values. Instead, the graph that's plotted is always that of the original-size while the x- and y-axis will adjust. Below is an example using the mtcars data in R.
library(sjPlot)
library(sjmisc)
library(ggplot2)
mtcars.df <- mtcars
fit <- lm(mpg ~ hp * disp, data = mtcars.df)
plot_model(fit, type = "pred", terms = c("hp", "disp"))
I can get a graph like this in my own code. However, when I attempt to alter the x- and y-axes as seen below, the grid expands, but the graph itself does not.
plot_model(fit, type = "pred", terms = c("hp", "disp"), axis.lim = list(c(0,150),c(0,200)))
Picture of successfully graphed interaction with wildly exaggerated adjustments to the axes. The graph does not extend but the grid does.
What code can I use to adjust both the lines of my interaction effect AND those of the grid? Adjusting post-hoc with
plot_model(fit, type = "pred", terms = c("hp", "disp"))+xlim(0,150)
creates the same issue.
Post-hoc extending the graph creates the same issue.
plot_model will only plot interactions over the range of your original data. It's really not difficult to do it directly in ggplot though by feeding whatever x values you want into predict:
library(ggplot2)
mtcars.df <- mtcars
fit <- lm(mpg ~ hp * disp, data = mtcars.df)
new_df <- expand.grid(hp = 0:300, disp = c(106.78, 230.72, 354.66))
predictions <- predict(fit, new_df, se = TRUE)
new_df$mpg <- predictions$fit
new_df$upper <- new_df$mpg + 1.96 * predictions$se.fit
new_df$lower <- new_df$mpg - 1.96 * predictions$se.fit
new_df$disp <- factor(new_df$disp)
ggplot(new_df, aes(hp, mpg)) +
geom_ribbon(aes(ymax = upper, ymin = lower, fill = disp), alpha = 0.3) +
geom_line(aes(color = disp)) +
scale_fill_brewer(palette = "Set1") +
scale_color_brewer(palette = "Set1")
Created on 2022-05-21 by the reprex package (v2.0.1)
plot_model allow you to choose the range of the plot just adding the range in square braquets next to the selected variable <<[min,max]>>.
I think the easiest way would be the following:
plot_model(fit, type = "pred", terms = c("hp [0,300]", "disp"))
You can find more details here:
https://strengejacke.github.io/sjPlot/articles/plot_marginal_effects.html
I've seen several answers on how to change the order of facets by reordering the factor levels. But I would like to change the order in which the margin is presented. So basically have (all) displayed on the left panel before 4, 6, 8. Thanks in advance!
library(ggplot2)
qplot(mpg, wt, data=mtcars) + facet_grid(. ~ cyl, margins=TRUE)
How about
mtcars2 <- rbind(mtcars, within(mtcars, cyl <- "(All)"))
qplot(mpg, wt, data = mtcars2) + facet_grid(. ~ cyl)
I have a very sophisticated solution, you always could edit your grobs structure:
library(ggplot2)
gg = qplot(mpg, wt, data=mtcars) + facet_grid(. ~ cyl, margins=TRUE)
ggg = ggplotGrob(gg)
ggg$grobs = ggg$grobs[c(1,5,2:4,9,6:8,10:15,19,16:18,20:27)]
grid::grid.newpage()
grid::grid.draw(ggg)
I built a simple linear regression model, and produced some predicted values using the model. However, I am more interested in visualizing it on the graph, but I do not know how to add a legend to highlight original mpg values as 'black' and new predicted values as "red".
Data used in this example is mtcars dataset from datasets package
library(ggplot2)
library(datasets)
library(broom)
# Build a simple linear model between hp and mpg
m1<-lm(hp~mpg,data=mtcars)
# Predict new `mpg` given values below
new_mpg = data.frame(mpg=c(23,21,30,28))
new_hp<- augment(m1,newdata=new_mpg)
# plot new predicted values in the graph along with original mpg values
ggplot(data=mtcars,aes(x=mpg,y=hp)) + geom_point(color="black") + geom_smooth(method="lm",col=4,se=F) +
geom_point(data=new_hp,aes(y=.fitted),color="red")
scatter plot
Here is one idea. You can combine the predicted and observed data in the same data frame and then create the scatter plot to generate the legend. The following code is an extension of your existing code.
# Prepare the dataset
library(dplyr)
new_hp2 <- new_hp %>%
select(mpg, hp = .fitted) %>%
# Add a label to show it is predicted data
mutate(Type = "Predicted")
dt <- mtcars %>%
select(mpg, hp) %>%
# Add a label to show it is observed data
mutate(Type = "Observed") %>%
# Combine predicted data and observed data
bind_rows(new_hp2)
# plot the data
ggplot(data = dt, aes(x = mpg, y = hp, color = factor(Type))) +
geom_smooth(method="lm", col = 4, se = F) +
geom_point() +
scale_color_manual(name = "Type", values = c("Black", "Red"))
Here is another way of doing it without dplyr:
ggplot() +
geom_point(data = mtcars, aes(x = mpg, y = hp, colour = "Obs")) +
geom_point(data = new_hp, aes(x = mpg, y = .fitted, colour = "Pred")) +
scale_colour_manual(name="Type",
values = c("black", "red")) +
geom_smooth(data = mtcars, aes(x = mpg, y = hp),
method = "lm", col = 4, se = F)
I am trying to layout 2 plots together using ggplot2 and plotly. Here's what I tried:
library(ggplot2)
library(plotly)
mt_mpg <- ggplot(data = mtcars)+
geom_boxplot(aes(x = as.factor(cyl), y = mpg))+
ggtitle("mpg vs cyl")
mt_disp <- ggplot(data = mtcars)+
geom_boxplot(aes(x = as.factor(cyl), y = disp))+
ggtitle("disp vs cyl")
subplot(mt_mpg, mt_disp)
Everything works great but the title of the combined plot only contains "disp vs cyl". I want to include both titles on the top of their corresponding plots. But I don't see any option in subplot() command to do so. Any ideas how this can be fixed? Thanks.
one way is to use facet_wrap instead of ggtitle. For example:
df <- mtcars
df$lab1 <- 'mpg vs cyl'
df$lab2 <- 'disp vs cyl'
mt_mpg <- ggplot(df)+
geom_boxplot(aes(x = as.factor(cyl), y = mpg))+
facet_wrap(~lab1)
mt_disp <- ggplot(df)+
geom_boxplot(aes(x = as.factor(cyl), y = disp))+
facet_wrap(~lab2)
subplot(mt_mpg, mt_disp)
Cheers,
Branden
How do I show 2 regression lines on the same plot?
Here are both models:
data(mtcars)
a <- lm(mpg~wt+hp)
b <- lm(mpg~wt+hp+wt*hp)
I plot wt on the x-axis, mpg on the y-axis and hp as the colour.
Here it is in base R:
cr <- colorRamp(c("yellow", "red"))
with(mtcars, {
plot(wt, mpg, col = rgb(cr(hp / max(hp)), max=255),
xlab="Weight", ylab="Miles per Gallon", pch=20)
})
Also, please show how to accomplish this in ggplot2.
Here's the plot:
library(ggplot2)
p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point(aes(col = hp))
p + scale_colour_gradientn(colours=c("green","black"))
Thanks in advance!
The documentation for geom_smooth practically tells you how to do this.
One can use the regression models to predict new values for y and then plot these on the same graph using geom_smooth().
Below is code for ggplot2 that produces what I think you want. The two lines overlap so much that it looks like only one line is plotted and I've set one linetype to dashed to demonstrate this.
I don't know how to achieve this in base R though.
data(mtcars)
library(ggplot2)
a <- lm(mpg~wt+hp, data = mtcars)
b <- lm(mpg~wt+hp+wt*hp, data = mtcars)
mtcars$pred.a <- predict(a)
mtcars$pred.b <- predict(b)
p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point(aes(col = hp)) +
scale_colour_gradientn(colours=c("green","black")) +
geom_smooth(aes(x = wt, y = pred.a), method = "lm", colour = "black", fill = NA) +
geom_smooth(aes(x = wt, y = pred.b), method = "lm", colour = "red", fill = NA, linetype = 4)
p
A base R solution:
a <- lm(mpg~wt+hp, data=mtcars)
b <- lm(mpg~wt+hp+wt*hp, data=mtcars)
wt <- mtcars[, "wt"]
idx <- sort(wt, index.return=TRUE)$ix
plot(mpg~wt, data=mtcars)
lines(wt[idx], predict(a)[idx], col="red")
lines(wt[idx], predict(b)[idx], col="blue")
However, it is not the best visualisation conceivable.
You are asking how to add a regression line, but your regression models produce a regression plane and a regression surface, both higher dimensional than a line. You can find a regression line by conditioning on a chosen value of hp, or show multiple lines for different values of hp.
Using base graphics you can use the Predict.Plot function in the TeachingDemos package to add prediction lines/curves to a plot for a fitted model (or 2). The interactive TkPredict' function in the same package will let you interact with the plot to choose conditioning values, then will produce the call toPredict.Plot` to create the current line. You can the combine the generated commands to include them on the same plot.