strengejacke / sjPlot

sjPlot - Data Visualization for Statistics in Social Science
https://strengejacke.github.io/sjPlot
606 stars 91 forks source link

Confidence interval bands partially or completely disappear when axes rescaled #933

Open gfschnei opened 5 months ago

gfschnei commented 5 months ago

Hi Dr. Luedecke - thanks for all your work on this amazing package! I am working on plotting the marginal effects for a GLM with two numerical explanatory variables. Here is the model with the variables genericized:

mod.example <- glm(y ~ x1*x2, family = poisson(link='log'), data = data) I want to use sjPlot to visualize the response variable across x1 at various levels of x2. plot_model(mod.example, type = "eff", terms = c("x1", "x2")) Rplot_example_ydefault The resulting has a y-axis that is out of proportion due to the large confidence interval of the predicted curve for x2 = 8. When I rescale the y-axis, either by adding "axis.lim =" to the plot code: plot_model(mod.example, type = "eff", terms = c("x1", "x2"), axis.lim = c(0,500)) or by rescaling with ggplot: p <- plot_model(mod.example, type = "eff", terms = c("x1", "x2"), axis.lim = c(0,500)) p + scale_y_continuous(limits = c(0, 500)) The rescaled plot shows the predicted curves at the scale I want, but the confidence interval bands/ribbons disappear or are only visible over part of the curves' length: Rplot_example_ylim1000 Rplot_example_ylim250 The rescaling code does throw a warning message that may be a clue to what is going wrong: "Warning message: Removed 3 rows containing missing values (geom_line())."

Any insights or work-arounds would be much appreciated! Thank you, Jerry S

sparsity-blues commented 2 weeks ago

i am having this same issue when trying to plot a 3-way interaction. this remains even when there are no removed rows for missing values.

any help would be much appreicuated!

strengejacke commented 2 weeks ago

Can you try:

ggeffects::predict_response(mod.example, terms = c("x1", "x2")) |> plot()
sparsity-blues commented 2 weeks ago

i wind up with the same issue, although since i have a 3 way interaction, in my case it is:

ggeffects::predict_response(mod.example, terms = c("x1", "x2", "x3")) |> plot()

x1 is a 4 level, unordered factor and x2 and x3 are continuous variables that have been centered and scaled. this is an nb model with an log-transformed offset, if that helps

sparsity-blues commented 2 weeks ago

not sure if this helps or not, but i made a df using ggeffects and noticed that the largest value of the "conf.high" column is 76.25. if i set my y scale to c(0, 77) the CI bands look fine. but if i go below the max, i get the cut-off CI band.

this happens at each grouping level of x1. so as long as the upper limit of the y scale is above the max "conf.high" value for the x1 grouping, the CI bands look ok. but for any x1 group that has a conf.high above the upper end of the y scale, the CI bands partially disappear.

for example, if i set the upper scale to 56, this leads to 2 plots with wonky CI bands, and 2 with no problems.

sparsity-blues commented 2 weeks ago

this gets me the plot of interest, using the df created with predict_response:

edit: i accidentally cropped the last line of code with the y limits

ggplot(mydf, aes(x, predicted, colour = group)) + geom_ribbon(aes(ymin = conf.low, ymax = conf.high, fill = group, linetype = NA, alpha = 0.01)) + geom_line()+ facet_wrap(~facet)+ coord_cartesian(ylim = c(0, 50))

strengejacke commented 2 weeks ago

yes, if the values of the confidence intervals exceed the axis limits, they're "cropped". that's the default ggplot2-behaviour. I think you can avoid this by adding a coord_cartesian() layer to the plot, e.g.

ggeffects::predict_response(mod.example, terms = c("x1", "x2", "x3")) |>
  plot() +
  ggplot2::coord_cartesian()

or you change the y-limits:

ggeffects::predict_response(mod.example, terms = c("x1", "x2", "x3")) |>
  plot() +
  ggplot2::ylim(c(..., ...))

# or
ggeffects::predict_response(mod.example, terms = c("x1", "x2", "x3")) |>
  plot(limits = c(..., ...)

See examples here: https://strengejacke.github.io/ggeffects/articles/introduction_plotcustomize.html#changing-the-y-axis-appearance

sparsity-blues commented 2 weeks ago

i'll keep working through examples, but so far (using the suggestions above), i still get the same truncated CI bands.

thanks!

strengejacke commented 2 weeks ago

Strange, it should work as described here: https://stackoverflow.com/questions/38777337/ggplot-ribbon-cut-off-at-y-limits

sparsity-blues commented 2 weeks ago

it does work with coord_cartesian(ylim = c(0, 50)), but only when i plot directly with ggplot on the ggeffcts object. i can't get it to work through ggeffects |> plot.