## sjPlot-package

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

!

### Description

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.

### GitHub

You can download the latest development build from github.

### Bug reports

Please submit bugs, issues and feature requests at github.

### sjmisc-package

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")`

.

#### Description

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.

#### GitHub

You can download the latest development build from github.

#### Bug reports

Please submit bugs, issues and feature requests at github.

## Documentation

### Basics of the sjPlot and sjmisc packages

- Data initialization
- Customize plot appearance
- Basics of sjt table-functions
- Inspecting (SPSS imported) data frames
- Global options settings

### 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
- sjp.int – 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)**

- Related Posting: Simplify your R workflow with functions

**sji.viewSPSS (View imported SPSS datasets)**

- Related Posting: Beautiful table outputs in R, part 2

**sjp.corr (Plot correlation matrix)**

- Related Posting: Examples for sjPlotting functions, including correlations and proportional tables with ggplot

**sjp.emm.int (Plot estimated marginal means of ANCOVA)**

- Related Posting: Visualize pre-post comparison of intervention

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

- Related Posting: Simplify frequency plots with ggplot in R

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

- Related Posting: Plotting lm and glm models with ggplot

**sjp.glmm (compare multiple models)**

- Related Posting: Comparing multiple (g)lm in one graph

**sjp.grpfrq (Plot grouped or stacked frequencies)**

- Related Posting: Easily plotting grouped bars with ggplot

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

- Related Posting: Plotting Likert-Scales (net stacked distributions) with ggplot

**sjp.lm (Plot beta coefficients of lm)**

- Related Posting: Plotting lm and glm models with ggplot

**sjp.lmint (Plot interaction terms of linear models)**

**sjp.pca (Plot PCA results)**

- Related Posting: Plotting principal component analysis with ggplot

**sjp.scatter (Scatter plots)**

- Related Posting: Simply creating various scatter plots with ggplot

**sjp.stackfrq (Plot stacked proportional bars)**

- Related Posting: Plotting Likert-Scales (net stacked distributions) with ggplot

**sjp.xtab (Plot proportional crosstables)**

- Related Posting: Examples for sjPlotting functions, including correlations and proportional tables with ggplot

**sjt.corr (Print correlation tabeles)**

- Related Posting: Beautiful table outputs in R, part 2

**sjt.df (Description of data frames)**

- Related Posting: Beautiful table outputs in R, part 2

**sjt.frq (Print frequency tables)**

- Related Posting: No need for SPSS – beautiful output in R

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

- Related Posting: Print glm-output to HTML table

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

- Related Posting: No need for SPSS – beautiful output in R

**sjt.pca (Print PCA as HTML-table)**

- Related Posting: Beautiful table outputs in R, part 2

**sjt.stackfrq (Print stacked frequencies and Likert scales)**

- Related Posting: Beautiful table outputs in R, part 2

**sjt.xtab (Print contingency tables)**

- Related Posting: No need for SPSS – beautiful output in R

There’s nice work here. You might want to look at GGally for similar work on quickly getting plots done with ggplot2.

Thanks for the hint, I’ll take a look at GGally!

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!

Ryan

Hi, please see examples at the end of this posting and in this comment. It depends on the function how you can change the border. For

`sjt.lm`

or`sjt.glm`

use the parameter`CSS=list(css.topborder="border-top:1px solid black;")`

.Thank you for creating this package it’s so great.

Hi Daniel,

Thanks a lot for your great package. How to use ggthemr-package along with sjplots?

Hi Rajee,

I have examples at the end of this manual. You need version 1.4.4 of the sjPlot-package, which is currently only available as development snapshot (https://github.com/sjPlot/devel).

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

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 🙂

What a package! Wunderbar! I have to pay you a beer. Vielen Dank!

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.

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?

Simply use following Code: `r sjt.frq(efc$e15relat, no.output=TRUE)$knitr`

See following manual: http://www.strengejacke.de/sjPlot/sjtbasics/

Hello, is there a way to change the linetype in sjp.int (from lme). I would like to have non colored plots.

Hello, is there a way to change the linetype in sjp.int. I would like to have plot without colours.

Thanks for your work …

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.

Hi Daniel, thanks so much for your efforts to develop all this! Your sjp.int 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!

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“, show.se = 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?

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.

Horst

Thanks for reporting this issue. Do you have a reproducible example? This would it make easier to track down the error.

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.

library(sjPlot)

#generate data

factor1<-rep(c("a","b","c", "d"),100)

var1<-sample(50:60,400,replace=T)

y<-sample(0:1,400,replace=T)

data<-data.frame(cbind(y,factor1,var1))

data$var1<-as.numeric(data$var1)

#fit logistic model

fit1<-glm(y~factor1+var1,family=binomial(link="logit"),data=data)

fit2<-glm(y~var1+factor1,family=binomial(link="logit"),data=data)

#plot model

sjp.glm(fit1,sortOdds=F)

sjp.glm(fit2,sortOdds=F)

I hope it will help.

Horst

Thanks, helped indeed. I improved the automatic label detection, will commit an update to GitHub tonight.

Hi Daniel; This package is really useful thanks a lot. I have one question about spj.int: 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?

C-

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.

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

sjp.int(np1, type = "eff", int.term=" as.factor(In) * as.factor(De)",show.ci = T, geom.colors = c("blue", "red"), jitter.ci=T)

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

Thanks

And „De“ and „In“ are categorical variable with 2 levels, pup is a integer

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)

enclo<-sample(1:12,200,replace=T)

Sim<-data.frame(cbind(den,pup,Infe, enclo))

Sim$pup<-as.numeric(Sim$pup)

Sim$enclo<-as.factor(Sim$enclo)

Sim$pup<-as.numeric(Sim$pup)

#fit logistic model

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

summary(fit1)

#plot interaction

sjp.int(fit1, type = "eff", int.term=" den*Infe",show.ci = T, geom.colors = c("blue", "red"),jitter.ci=T)

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

Great, thank you 🙂

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 <- sjp.int(model, type="eff", show.ci=T)

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!!

Do you have a reproducible example? I can change the y-axis title this way, w/o any loss of plot elements.

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 <- sjp.int(model,type="eff", show.ci=TRUE, 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")

dev.off()

Many thanks!

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

`jitter.ci = T`

to the sjp.int-call.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"), show.ci = TRUE, facet.grid = FALSE)

Thanks!!

I need some more information to be sure, but I guess, since each category of Grass has an own slope, the lines are not parallel.

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!

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!

Hi Daniel, Is there a way to plot standard error instead of confidence interval bands in the sj.int for a glmer model?

thanks so much,

Sarah

Hi,

I am working with sjp.int 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:

model

You could try the ggeffects-package, namely the

`ggpredict()`

function. There’s a package vignette describing how to plot predicted values, including 2- and 3-way-interaction. Also, see this blog post.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.

Could you please check whether the same bug occurs when you use plot_model() instead?

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.

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

It’s a bit difficult to address this issue here. Please submit an issue at https://github.com/strengejacke/sjPlot/issues, and provide a reproducible example. This should help me solving the problem.