Reputation: 65
I can't figure out how to change the shape of the points in sjplot or ggeffects - I have
in sJplot:
p<-plot_model(my.lm, type = "pred", terms = c("Var1", "Var2", "Var3"))
This makes the points of Var 2 different colors, but I need them to be different shapes.
I can use ggeffects for this, but I still can't figure out how to make an equivalent graph to plot_model in sJplot with different point shapes.
g<-ggpredict(my.lm, terms=c("Var1","Var2", "Var3"))
Thank you
Upvotes: 0
Views: 992
Reputation: 13843
There doesn't seem to be a simple way to do this (like an argument within plot_model()
). So, it seems the only option here is the "nuclear option" - which is changing the values in the $data
layer of the plot object. It gets a bit "hacky", but it does work.
I'll demonstrate based on an adaptation of an example in this vignette here.
library(ggplot2)
library(sjPlot)
library(sjmisc)
library(sjlabelled)
data(efc)
y <- ifelse(efc$neg_c_7 < median(na.omit(efc$neg_c_7)), 0, 1)
df <- data.frame(
y = to_factor(y),
sex = to_factor(efc$c161sex),
dep = to_factor(efc$e42dep),
barthel = efc$barthtot,
education = to_factor(efc$c172code)
)
set_label(df$y) <- "High Negative Impact"
fit <- glm(y ~., data = df, family = binomial(link = "logit"))
p <- plot_model(fit, colors = "black")
p
Our goal is to change the shape of those points to something else. First step is to use ggplot_build()
to pull the information from the object we just created, p
.
qq <- ggplot_build(p)
The object, qq
, is a list containing 3 layers: data, layout, and plot. Herein, we want to change the information contained in qq$data
, which has the aesthetics after they have been mapped. qq$data
is a list itself, containing 3 tables. Each of these tables corresponds to a particular geom in the underlying ggplot2
call. The first table qq$data[[1]]
, is for the vline geom. The third table qq$data[[3]]
is for all the line segments behind the points (you'll note they have xmin, xmax, ymin, and ymax columns). The second table is the one we want, which is for the point geoms:
> qq$data[[2]]
colour fill x y PANEL group shape size alpha stroke
1 black black 7 0.28191638 1 7 19 2.5 NA 0.5
2 black black 6 0.21074532 1 6 19 2.5 NA 0.5
3 black black 5 0.48863767 1 5 19 2.5 NA 0.5
4 black black 4 0.39529220 1 4 19 2.5 NA 0.5
5 black black 3 -0.01294270 1 1 19 2.5 NA 0.5
6 black black 2 0.09837842 1 3 19 2.5 NA 0.5
7 black black 1 0.12316583 1 2 19 2.5 NA 0.5
You can see all points are made with shape=19
. We can change that, then rebuild the plot from our modified qq
object like so:
qq$data[[2]]$shape <- 5
plot(ggplot_gtable(qq))
We can do fun things like change all sorts of stuff manually in the plot if you want:
qq$data[[1]]$colour <- "blue" # change color of vertical line
qq$data[[2]]$shape[3:5] <- 19 # points 3-5 are now circles again
qq$data[[2]]$color[4:7] <- "red" # last 4 point are red
qq$data[[2]]$size[c(2,4,6)] <- 4 # some points are bigger
plot(ggplot_gtable(qq))
A word on saving these files plots to file, if you like to use ggsave(...)
: You cannot save the output of plot(ggplot_gtable(qq))
directly using ggsave()
, since the default value for plot=
in ggsave()
is last_plot()
, which does not work here when using plot(...)
. Therefore if you want to save with ggsave()
, you can do the following:
p <- ggplot_gtable(qq) # save to a large gtable
ggsave("name.png", plot = p # reference the gtable object
Upvotes: 2