sjPlot R-package


sjPlot is available on CRAN! You can install the package and its dependencies using install.packages("sjPlot")!


Collection of plotting and table output functions for data visualization. Results of various statistical analyses (that are commonly used in social sciences) can be visualized using this package, including simple and cross tabulated frequencies, histograms, box plots, (generalized) linear models, mixed effects models, PCA and correlation matrices, cluster analyses, scatter plots, Likert scales, interpretation of interaction terms in regression models, constructing index or score variables and much more.


You can download the latest development build from github.

Bug reports

Please submit bugs, issues and feature requests at github.


A package related to sjPlot is the sjmisc package, which is also
available on CRAN.
You can install the package and its dependencies with install.packages("sjmisc").


This package contains some tools that are useful when carrying out data analysis or interpreting data
(especially intended for people coming from SPSS and/or who are new to R). These tool functions
support reading and writing data (SPSS, SAS and STATA), variable recoding and weighting, variable labeling,
statistical tests, reliability tests and much more.


You can download the latest development build from github.

Bug reports

Please submit bugs, issues and feature requests at github.


Basics of the sjPlot and sjmisc packages

Plotting functions

  • sjp.frq – plot frequencies of (count) variables
  • sjp.glm – plot odds ratios (forest plots) of generalized linear models
  • sjp.glmer – plot odds ratios (forest plots) of generalized linear mixed effects models
  • sjp.grpfrq – plot grouped or stacked frequencies
  • – plot interaction effects of regression models
  • sjp.likert – plot Likert scales
  • sjp.lm – plot estimates of linear models
  • sjp.lmer – plot estimates (forest plots) of linear mixed effects models
  • sjp.pca – plot principal component analysis
  • sjp.scatter – plot (grouped) scatter plots
  • sjp.stackfrq – plot stacked proportional bars
  • sjp.xtab – plot contingency tables

Table functions

  • sjt.corr – correlations as HTML table
  • sjt.df – (description of) data frames as HTML table
  • sjt.frq – frequencies of (count) variables as HTML table
  • sjt.lm – linear models as HTML table
  • sjt.pca – principal component analysis as HTML table
  • sjt.stackfrq – stacked frequencies as HTML table
  • sjt.xtab – contingency tables as HTML table


Blog posts with examples of some functions

Note that, due to further development, some examples from the below listed blog posting might be out of date! Please refer to the package help (?sjp.-funcName-) for latest working examples!

sji.SPSS (Import SPSS dataset as data frame into R)

sji.viewSPSS (View imported SPSS datasets)

sjp.corr (Plot correlation matrix) (Plot estimated marginal means of ANCOVA)

sjp.frq (Plot frequencies of (count) variables)

sjp.glm (Plot odds ratios (forest plots))

sjp.glmm (compare multiple models)

sjp.grpfrq (Plot grouped or stacked frequencies)

sjp.likert (Plot likert scales as centered stacked bars)

sjp.lm (Plot beta coefficients of lm)

sjp.lmint (Plot interaction terms of linear models)

sjp.pca (Plot PCA results)

sjp.scatter (Scatter plots)

sjp.stackfrq (Plot stacked proportional bars)

sjp.xtab (Plot proportional crosstables)

sjt.corr (Print correlation tabeles)

sjt.df (Description of data frames)

sjt.frq (Print frequency tables)

sjt.glm (Print odds Ratios as HTML-Table)

sjt.lm (Print linear models as HTML-Table)

sjt.pca (Print PCA as HTML-table)

sjt.stackfrq (Print stacked frequencies and Likert scales)

sjt.xtab (Print contingency tables)


56 Kommentare zu „sjPlot R-package

  1. Howdy Strenge Thanks for you great job!
    The horizontal borders in default are set as double lines in the output table. How can I change them into single lines, which are required by APA style.

    Thanks so much!


  2. This package is absolutely wonderful, but how can we use it to visualize results from Cox regressions, using the survival package (coxph function).

  3. That’s probably my favorite R package of the months, thanks a lot for this!
    Tables like this have been the only thing I missed in R, so I’m disturbingly excited about this.

    I hope you’ve gained enough support to improve and maintain the package, I’m hoping to recommend it to a whole bunch of people 🙂

  4. Daniel,
    Thank you so much for this package! I use it almost every day. It is wonderful. It makes my reports for behavioral health programs at San Francisco Department of Public Health beautiful and meaningful.

  5. Amazing package and exactly what I was looking for. Only issue I am having right now is that whenever I try to put sjt.frq into a knitr document, the resulting HTML document losses the formatting for the table. Any way to fix that?

    1. Currently, you can only plot in grey-scale, but not in b/w with different line types. However, I have thought about this option, too. This might be a feature for a next update.

      1. Hi Daniel, thanks so much for your efforts to develop all this! Your function is super convenient and easy to use. That said, I would like to follow up on saalchris’s question whether it is possible (by now) in any way to have different linetypes instead of different colors for the various slopes. I would like to use the output for an article that will be printed in b/w and it is very hard to visually associate the slopes‘ colors with the legend, especially when confidence intervals are plotted, too. Thank you!

  6. Dear Daniel, I have to say thank you for your wonderful package. I was wondering if everything is alright with argumentation for plots. I am currently working on glm model and I wanted to add new labels to independent variables. I do the following:

    sjp.glm(model2, type = „prob“, = TRUE,
    axisLabels.y = c(„Age“, „Education“), geom.colors=“ds“)

    Unfortunately, labels does not change as well as grey palette, which I specify with „gs“. I probably do something wrong. Could you please help me with that?

  7. Dear Daniel
    Thank you for this amazing package.
    I’m not sure if this is the right place for my question.
    I came across an issue with the odds ratio plot. I used it to plot the odds ratios for a logistic model with several continuous variables and several factor variable with more than two levels. In my model formula, they are mixed in the form:
    fit<-glm(y~factor1+continuous_var1+factor2+continuous_var2 and so on.
    When I call the sjp.glm(fit1) I get the odds ratio plot, but their are some weird odds included. Say, for example the factor 1 has the levels a, b, c. In the plot they are correctly listed, but additionally a new factor, which doesn't exist appears. To keep with the example, it would be named factor1a. Also, some actual existing variables are omitted in the plot. This doesn't happen, when I order the model in the form:
    fit<-glm(y~continuous_var1+continuous_var2+factor1+factor2 and so on.
    I just thought you might want to know this issue.

  8. Hi
    I put together this little example. As i wrote it, I found out, that you don’t need more than one factor and continuous variable. The error occours with one of each, too.
    #generate data
    factor1<-rep(c("a","b","c", "d"),100)
    #fit logistic model
    #plot model

    I hope it will help.

  9. Hi Daniel; This package is really useful thanks a lot. I have one question about when plotting interaction between categorical variables, I couldn’t find the way to remove the line between the points (it doesn’t make sense when x is categorical) and also I couldn’t use jitter to avoid the overlapping CI (probably because the x axis is categorical?). Is there anyway to do this?

    1. Hi Claire, do you have a reproducible example? For me, jittering works. The line, however, cannot be removed, though I would admit that categorical values would / should not need lines to connect the data points… I will think about it.

      1. Hey, thanks for this quick answer.
        Sorry I couldn’t simulate a dataset for this, but here are the code that I am running:

        My model is
        np1<-glmer.nb(NP~as.factor(In)+ as.factor( De)+ as.factor(In) * as.factor(De)+ (1|enclo), data=dat)
        THEN, type = "eff", int.term=" as.factor(In) * as.factor(De)", = T, geom.colors = c("blue", "red"),

        And it gives me an interaction plot where the error bar are overlapping

  10. OK, Here is a reproducible example 🙂
    #generate data
    den<-sample(c("lo","hi"),200, replace=T)
    pup<-rnegbin(200, mu = 3, theta = 2)
    Infe<-sample(c("I", "NI"), 200, replace=T)
    Sim<-data.frame(cbind(den,pup,Infe, enclo))

    #fit logistic model
    fit1<-glmer.nb(pup~den*Infe+(1|enclo), data=Sim)

    #plot interaction, type = "eff", int.term=" den*Infe", = T, geom.colors = c("blue", "red"),

    1. Thanks, found the bug, fixed now. Package-update will need some time, though, because other dependency-packages have to be updated first…

  11. Love this!!! An easy way to plot your model slopes (without going through the hassles of extracting them and plotting with ggplot!). Is there a way to change the Y-axis label? I tried to do with

    dummy <-, type="eff",
    dummy$plot.list[[1]]+labs(y="label", x"label")

    It works, but my confidence intervals are not longer showing in these nice colored bands (but the error bars pop up), such a pity.
    That is the only thing I would change, the rest is awesome!! Saves me so much time!!

      1. Hi Daniel, Thanks for you quick reply and help!
        Here is may example (first time ever, so maybe there are better ways to do it, but it works :):

        mydata <- data.frame( SID=sample(1:150,400,replace=TRUE),age=sample(50:70,400,replace=TRUE), sex=sample(c("Male","Female"),200, replace=TRUE),time= sample(1:6,400, replace=TRUE), Vol =rnorm(400),HCD =rnorm(400))
        mydata$time <- as.numeric(mydata$time)

        model = lme(Vol ~ age+sex*time+time* HCD, random=~1|SID, na.action="na.omit",data=mydata);summary(model)

        png(filename="longHCD.png", width=25, height=20, units="cm", bg="white", res=180)
        sjp.setTheme(base=theme_classic(), axis.linecolor="black")
        dummy <-,type="eff",, swap.pred=TRUE, mdrt.values="quart", title="", axis.title="Time", legend.title="Hippocampal density", fill.alpha=0.1)
        dummy$plot.list[[1]]+labs(y="Predicted brain volume", x="Time")+scale_x_continuous(name="Time")

        Many thanks!

    1. Ok, working as intended. For categorical predictors, the plot creates error bars, but no CI-bands. For the 2nd plot, bands are still there:
      dummy$plot.list[[2]] + labs(y=“Predicted brain volume“, x=“Time“)
      If you want to avoid overlapping of error bars, add the argument = T to the

  12. Thanks for this amazing package, such nice plots! I’m struggling however to understand why my model which contains one continuous (OT) and one categorical (Grass) fixed effect and a random intercept (Site) is producing plots where the lines for each factor level are not parallel. There are no interaction terms or random slope component. Any ideas?
    mod <- lmer(Ht ~ OT + Grass + (1|Site), data = dat)
    sjp.lmer(mod, type = "pred.fe", vars = c("OT", "Grass"), = TRUE, facet.grid = FALSE)

  13. Writing again as my question dissapeared – the package looks great! I’m trying to plt interactions of two categorical variables, for some reason the plot choose the order of levels on x axis in alphabetical order – High, Low, Medium. The variable was defined as factor with the correct order of levels ( factor(test.dt$VisitLevel, levels=c(„Low“,“Medium“,“High“)), and I even check it (printed the levels() of the variable…. What have I missed? I also tried to add ,axis.labels =c(„Low“,“Medium“,“High“) but it didnt‘ help….
    Many thanks!

  14. Hi Daniel! Thank you very much for the package, great job!
    I am making a plot with several models that share the response variable and differ in their predictors (with sjp.lmm), and I am wondering how I can change the order of predictor variables in the y-axis, which is by alphabetical order by default. I would have thought that „axis.labels“ would do that, but it doesn’t work. Actually, in order to match the labels that you put in „axis.labels“ with the actual variable names in the y- axis of the plot, it seems that you have to sort them according to the estimates values…

    Thank you!

  15. Hi Daniel, Is there a way to plot standard error instead of confidence interval bands in the for a glmer model?
    thanks so much,

  16. Hi,
    I am working with to plot the interaction effects in a lmer model.
    I have two questions.
    First, I want to print the values of the predicted variable per group in the plot with two digits but it shows always only one – irrespectively of .
    Second, I want to plot the lines in black/white and use different line types to distinguish groups. To do so, I tried to use . However, doing so, legend.title and legend.labels are no longer as specified (they appear automatically as coded in the data set with numbers instead of the description I want to have). Using prints the labesl correctly (but of course, the lines are not longer bw).

    What am I doing wrong? Do you have any ideas?
    Thank you, Marion

    See below for my model:

  17. I think there is a small bug in sjt.glmer. If you execute a glmer with family = Gamma, the default link is ‚inverse‘ but sjt.glmer acts as if ‚log‘ was the linking function in computing the coefficients. The estimates are way off. If, however, you specify the link function as ‚log‘ in the original equation, the estimates are correct. If you use the default inverse link and ask sjt.glmer to print the family, it correctly prints ‚inverse‘ but it uses log anyway.

  18. Not sure what’s going on with plot_model(). The dependent variable is reaction time recorded as decimal seconds. The range across all subjects is .445 to .897 with a median of .504. The effects are small, one the 20-30 msec which is .025 ish. If I use ‚inverse‘ as the link function, sjt.glmer lists the intercept as 7.87 (or 7800 msec) which can’t be. In sjt.glmer the other three fixed effect parameters look about right. They range between .97 and 1.01. Since they are likelihood ratios, they seem about right. sjp.glmer lists similar values for the fixed effect parameters but does not list the intercept. plot_model list the three fixed effects parameters from -.02 to +.02. These would make no sense as likelihood parameters but would be approximately right as linear parameters.

  19. Actually plot_model() is plotting the raw parameters, whereas the other sj functions are plotting transformed parameters.

  20. Hello Daniel,
    I’m using your Package to build a nice R markdown Report. Your Package is very nice and helpful – many thanks for that.
    But I got an Encoding Problem. Try this and check it by yourself:


    1. Oh, my example is cutted off. Here again:

      Var1 <- factor(sample(1:6, 200, replace = T))
      Var1 <- factor(Var1,
      levels = c("1","2","3","4","5", "6"),
      labels = c("Zu Hause",
      "Am Arbeitsplatz bzw. im Büro",
      "In der Schule bzw. an der Universität",
      "An einem öffentlichen Ort, z.B. im Internet-Café oder an einem Multimedia-Terminal",
      "Unterwegs, z.B. über einen mobilen Internetzugang, Hotspot/WLAN oder über ein Smartphone",
      "Woanders außer Haus, z.B. bei Freunden oder Verwandten"))

      sjt.xtab(Var1, Var1)

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

Du kommentierst mit Deinem Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )


Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )


Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )


Verbinde mit %s