{"id":3056,"date":"2023-05-08T04:26:35","date_gmt":"2023-05-08T04:26:35","guid":{"rendered":"http:\/\/optimumsportsperformance.com\/blog\/?p=3056"},"modified":"2023-05-08T12:28:52","modified_gmt":"2023-05-08T12:28:52","slug":"plotting-mixed-model-outputs","status":"publish","type":"post","link":"https:\/\/optimumsportsperformance.com\/blog\/plotting-mixed-model-outputs\/","title":{"rendered":"Plotting Mixed Model Outputs"},"content":{"rendered":"<p>This weekend I posted two new blog articles about building reports that contained both data tables and plots on the same canvas (see <strong><span style=\"color: #0000ff;\">HERE<\/span><\/strong> and <strong><span style=\"color: #0000ff;\"><a style=\"color: #0000ff;\" href=\"https:\/\/optimumsportsperformance.com\/blog\/displaying-tables-plots-together-part-2-adding-titles-captions\/\">HERE<\/a><\/span><\/strong>). As a follow up, <strong><span style=\"color: #0000ff;\"><a style=\"color: #0000ff;\" href=\"https:\/\/twitter.com\/jamesbaker_8\">James Baker<\/a><\/span><\/strong> asked if I could do some plotting of mixed model outputs. That got me thinking, I&#8217;ve done a few blog tutorials on mixed models (see <strong><span style=\"color: #0000ff;\"><a style=\"color: #0000ff;\" href=\"https:\/\/optimumsportsperformance.com\/blog\/mixed-models-in-sport-science-frequentist-bayesian\/\">HERE<\/a><\/span><\/strong> and <strong><span style=\"color: #0000ff;\"><a style=\"color: #0000ff;\" href=\"https:\/\/optimumsportsperformance.com\/blog\/making-predictions-from-a-mixed-model-using-r\/\">HERE<\/a><\/span><\/strong><span style=\"color: #000000;\">) and this got me thinking. Because he left it pretty wide open (<em>&#8220;Do you have any guides on visualizing mixed models?&#8221;<\/em>) I was trying to think about what aspects of the mixed models he&#8217;d like to visualize. R makes it relatively easy to plot random effects using the {<strong>lattice<\/strong>} package, but I figured we could go a little deeper and customize some of our own plots of the random effects as well as show how we might plot future predictions from a mixed model.<\/span><\/p>\n<p>All of the code for this article is available on my <strong><span style=\"color: #0000ff;\"><a style=\"color: #0000ff;\" href=\"https:\/\/github.com\/pw2\/Mixed-Models\/blob\/main\/Plotting%20Mixed%20Models.R\">GITHUB page<\/a><\/span><\/strong>.<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Loading Packages &amp; Data<\/strong><\/span><\/p>\n<p>As always we begin by loading some of the packages we require and the data. In this case, we will use the <em><strong>sleepstudy <\/strong><\/em>dataset, which is freely available from the {<strong>lme4<\/strong>} package.<\/p>\n<pre class=\"brush: r; title: ; notranslate\" title=\"\">\r\n## Load packages\r\nlibrary(tidyverse)\r\nlibrary(lme4)\r\nlibrary(lattice)\r\nlibrary(patchwork)\r\n\r\ntheme_set(theme_bw())\r\n\r\n## load data\r\ndat &lt;- sleepstudy dat %&gt;%\r\n  head()\r\n<\/pre>\n<p><span style=\"text-decoration: underline;\"><strong>Fit a mixed model<\/strong><\/span><\/p>\n<p>We will fit a mixed model that sets the dependent variable as Reaction time and the fixed effect as days of sleep deprivation. We will also allow both the intercept and slope to vary randomly by nesting the individual SubjectID within each Day of sleep deprivation.<\/p>\n<pre class=\"brush: r; title: ; notranslate\" title=\"\">\r\n## Fit mixed model\r\nfit_lmer &lt;- lmer(Reaction ~ Days + (1 + Days|Subject), data = dat)\r\nsummary(fit_lmer)\r\n<\/pre>\n<p><a href=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.02.51-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3057\" src=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.02.51-PM-1024x928.png\" alt=\"\" width=\"508\" height=\"460\" srcset=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.02.51-PM-1024x928.png 1024w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.02.51-PM-300x272.png 300w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.02.51-PM-768x696.png 768w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.02.51-PM-624x566.png 624w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.02.51-PM.png 1028w\" sizes=\"auto, (max-width: 508px) 100vw, 508px\" \/><\/a><\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Inspect the random effects<\/strong><\/span><\/p>\n<p>We can see in the model output above that we have a random effect standard deviation for the Intercept (24.84) and for the slope, Days (5.92). We can extract out the random effect intercept and slope for each subject with the code below. This tells us how much each subject&#8217;s slope and intercept vary from the population fixed effects (251.4 and 10.5 for the intercept and slope, respectively).<\/p>\n<pre class=\"brush: r; title: ; notranslate\" title=\"\">\r\n# look at the random effects\r\nrandom_effects &lt;- ranef(fit_lmer) %&gt;%\r\n  pluck(1) %&gt;%\r\n  rownames_to_column() %&gt;%\r\n  rename(Subject = rowname, Intercept = &quot;(Intercept)&quot;) \r\n\r\nrandom_effects %&gt;%\r\n  knitr::kable()\r\n<\/pre>\n<p><a href=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.05.24-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3058\" src=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.05.24-PM.png\" alt=\"\" width=\"352\" height=\"453\" srcset=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.05.24-PM.png 548w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.05.24-PM-233x300.png 233w\" sizes=\"auto, (max-width: 352px) 100vw, 352px\" \/><\/a><\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Plotting the random effects<\/strong><\/span><\/p>\n<p>Aside from looking at a table of numbers, which can sometimes be difficult to draw conclusions from (especially if there are a large number of subjects) we can plot the data and make some observational inference.<\/p>\n<p>The {<strong>lattice<\/strong>} package allows us to create waterfall plots of the random effects for each subject with the <strong>dotplot()<\/strong> function.<\/p>\n<pre class=\"brush: r; title: ; notranslate\" title=\"\">\r\n## plot random effects\r\ndotplot(ranef(fit_lmer))\r\n<\/pre>\n<p><a href=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.07.43-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3059\" src=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.07.43-PM-913x1024.png\" alt=\"\" width=\"465\" height=\"522\" srcset=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.07.43-PM-913x1024.png 913w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.07.43-PM-268x300.png 268w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.07.43-PM-768x861.png 768w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.07.43-PM-624x700.png 624w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.07.43-PM.png 1172w\" sizes=\"auto, (max-width: 465px) 100vw, 465px\" \/><\/a><\/p>\n<p>That&#8217;s a pretty nice plot and easy to obtain with just a single line of code. But, we might want to create our own plot using {<strong>ggplot2<\/strong>} so that we have more control over the styling.<\/p>\n<p>I&#8217;ll store the standard deviation of the random slope and intercept, from the model read out above, in their own element. Then, I&#8217;ll use the random effects table we made above, which contains the intercept and slope of each subject, to plot them and add the standard deviation to them as error bars.<\/p>\n<pre class=\"brush: r; title: ; notranslate\" title=\"\">\r\n## Make one in ggplot2\r\nsubject_intercept_sd &lt;- 24.7\r\nsubject_days_sd &lt;- 5.92\r\n\r\nint_plt &lt;- random_effects %&gt;%\r\nmutate(Subject = as.factor(Subject)) %&gt;%\r\nggplot(aes(x = Intercept, y = reorder(Subject, Intercept))) +\r\ngeom_errorbar(aes(xmin = Intercept - subject_intercept_sd,\r\nxmax = Intercept + subject_intercept_sd),\r\nwidth = 0,\r\nsize = 1) +\r\ngeom_point(size = 3,\r\nshape = 21,\r\ncolor = &quot;black&quot;,\r\nfill = &quot;white&quot;) +\r\ngeom_vline(xintercept = 0,\r\ncolor = &quot;red&quot;,\r\nsize = 1,\r\nlinetype = &quot;dashed&quot;) +\r\nscale_x_continuous(breaks = seq(-60, 60, 20)) +\r\nlabs(x = &quot;Intercept&quot;,\r\ny = &quot;Subject ID&quot;,\r\ntitle = &quot;Random Intercepts&quot;)\r\n\r\nslope_plt &lt;- random_effects %&gt;%\r\nmutate(Subject = as.factor(Subject)) %&gt;%\r\nggplot(aes(x = Days, y = reorder(Subject, Days))) +\r\ngeom_errorbar(aes(xmin = Days - subject_days_sd,\r\nxmax = Days + subject_days_sd),\r\nwidth = 0,\r\nsize = 1) +\r\ngeom_point(size = 3,\r\nshape = 21,\r\ncolor = &quot;black&quot;,\r\nfill = &quot;white&quot;) +\r\ngeom_vline(xintercept = 0,\r\ncolor = &quot;red&quot;,\r\nsize = 1,\r\nlinetype = &quot;dashed&quot;) +\r\nxlim(-60, 60) +\r\nlabs(x = &quot;Slope&quot;,\r\ny = &quot;Subject ID&quot;,\r\ntitle = &quot;Random Slopes&quot;)\r\n\r\nslope_plt \/ int_plt\r\n<\/pre>\n<p><a href=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.10.18-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-3060\" src=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.10.18-PM-1024x1019.png\" alt=\"\" width=\"625\" height=\"622\" srcset=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.10.18-PM-1024x1019.png 1024w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.10.18-PM-150x150.png 150w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.10.18-PM-300x300.png 300w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.10.18-PM-768x765.png 768w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.10.18-PM-624x621.png 624w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.10.18-PM.png 1360w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/p>\n<p>We get the same plot but now we have more control. We can color the dot specific subjects, or only choose to display specific subjects, or flip the x- and y-axes, etc.<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Plotting the model residuals<\/strong><\/span><\/p>\n<p>We can also plot the model residuals. Using the <strong>residual() <\/strong>function we can get the residuals directly from our mixed model and the <strong>plot()<\/strong> function with automatically plot the Residual and Fitted values. These types of plots are useful for exploring assumptions such as normality of the residuals and homoscedasticity.<\/p>\n<pre class=\"brush: r; title: ; notranslate\" title=\"\">\r\n## Plot Residual\r\nplot(fit_lmer)\r\nhist(resid(fit_lmer))\r\n\r\n<\/pre>\n<p><a href=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.21-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3061\" src=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.21-PM-1024x1010.png\" alt=\"\" width=\"298\" height=\"294\" srcset=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.21-PM-1024x1010.png 1024w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.21-PM-300x296.png 300w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.21-PM-768x758.png 768w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.21-PM-624x616.png 624w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.21-PM.png 1346w\" sizes=\"auto, (max-width: 298px) 100vw, 298px\" \/><\/a> <a href=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.31-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3062\" src=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.31-PM-1024x985.png\" alt=\"\" width=\"325\" height=\"312\" srcset=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.31-PM-1024x985.png 1024w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.31-PM-300x288.png 300w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.31-PM-768x739.png 768w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.31-PM-624x600.png 624w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.15.31-PM.png 1356w\" sizes=\"auto, (max-width: 325px) 100vw, 325px\" \/><\/a><\/p>\n<p>As above, perhaps we want to have more control over the bottom plot, so that we can style it however we&#8217;d like. We can extract the fitted values and residuals and build our own plot using base R.<\/p>\n<pre class=\"brush: r; title: ; notranslate\" title=\"\">\r\n## Plotting our own residual ~ fitted\r\nlmer_fitted &lt;- predict(fit_lmer, newdata = dat, re.form = ~(1 + Days|Subject))\r\nlmer_resid &lt;- dat$Reaction - lmer_fitted\r\n\r\nplot(x = lmer_fitted,\r\n     y = lmer_resid,\r\n     pch = 19,\r\n     main = &quot;Resid ~ Fitted&quot;,\r\n     xlab = &quot;Fitted&quot;,\r\n     ylab = &quot;Residuals&quot;)\r\nabline(h = 0,\r\n       col = &quot;red&quot;,\r\n       lwd = 3,\r\n       lty = 2)\r\n<\/pre>\n<p><a href=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.17.13-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3063\" src=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.17.13-PM-1024x1001.png\" alt=\"\" width=\"466\" height=\"456\" srcset=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.17.13-PM-1024x1001.png 1024w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.17.13-PM-300x293.png 300w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.17.13-PM-768x751.png 768w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.17.13-PM-624x610.png 624w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.17.13-PM.png 1338w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/a><\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Plotting Predictions<\/strong><\/span><\/p>\n<p>The final plot I&#8217;ll build are the predictions of Reaction time as Days of sleep deprivation increase. This is time series data, so I&#8217;m going to extract the first 6 days of sleep deprivation for each subject and build the model using that data. Then, make predictions on the next 4 days of sleep deprivation for each subject and get both a predicted point estimate and 90% prediction interval. In this way, we can observe the next 4 days of sleep deprivation for each subject and see how far outside of what we would expect (from our mixed model predictions) those values fall.<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"brush: r; title: ; notranslate\" title=\"\">\r\n### Plotting the time series on new data\r\n# training set\r\ndat_train &lt;- dat %&gt;%\r\n  group_by(Subject) %&gt;%\r\n  slice(head(row_number(), 6)) %&gt;%\r\n  ungroup()\r\n\r\n# testing set\r\ndat_test &lt;- dat %&gt;%\r\n  group_by(Subject) %&gt;%\r\n  slice(tail(row_number(), 4)) %&gt;%\r\n  ungroup()\r\n\r\n## Fit mixed model\r\nfit_lmer2 &lt;- lmer(Reaction ~ Days + (1 + Days|Subject), data = dat_train)\r\nsummary(fit_lmer2)\r\n\r\n# Predict on training set\r\ntrain_preds  &lt;- merTools::predictInterval(fit_lmer2, newdata = dat_train, n.sims = 100, returnSims = TRUE, seed = 657, level = 0.9) %&gt;%\r\n  as.data.frame()\r\n\r\ndat_train &lt;- dat_train %&gt;% bind_cols(train_preds)\r\n\r\ndat_train$group &lt;- &quot;train&quot;\r\n\r\n# Predict on test set with 90% prediction intervals\r\ntest_preds  &lt;- merTools::predictInterval(fit_lmer2, newdata = dat_test, n.sims = 100, returnSims = TRUE, seed = 657, level = 0.9) %&gt;%\r\n  as.data.frame()\r\n\r\ndat_test &lt;- dat_test %&gt;% bind_cols(test_preds)\r\n\r\ndat_test$group &lt;- &quot;test&quot;\r\n\r\n## Combine the data together\r\ncombined_dat &lt;- bind_rows(dat_train, dat_test) %&gt;%\r\n  arrange(Subject, Days)\r\n\r\n## Plot the time series of predictions and observed data\r\ncombined_dat %&gt;%\r\nmutate(group = factor(group, levels = c(&quot;train&quot;, &quot;test&quot;))) %&gt;%\r\nggplot(aes(x = Days, y = Reaction)) +\r\n  geom_ribbon(aes(ymin = lwr,\r\n                  ymax = upr),\r\n              fill = &quot;light grey&quot;,\r\n              alpha = 0.8) +\r\n  geom_line(aes(y = fit),\r\n            col = &quot;red&quot;,\r\n            size = 1) +\r\n  geom_point(aes(fill = group),\r\n             size = 3,\r\n             shape = 21) +\r\n  geom_line() +\r\n  facet_wrap(~Subject) +\r\n  theme(strip.background = element_rect(fill = &quot;black&quot;),\r\n        strip.text = element_text(face = &quot;bold&quot;, color = &quot;white&quot;),\r\n        legend.position = &quot;top&quot;) +\r\n  labs(x = &quot;Days&quot;,\r\n       y = &quot;Reaction Time&quot;,\r\n       title = &quot;Reaction Time based on Days of Sleep Deprivation&quot;)\r\n<\/pre>\n<p><a href=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.22.06-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-3064\" src=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.22.06-PM-1024x633.png\" alt=\"\" width=\"625\" height=\"386\" srcset=\"https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.22.06-PM-1024x633.png 1024w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.22.06-PM-300x185.png 300w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.22.06-PM-768x475.png 768w, https:\/\/optimumsportsperformance.com\/blog\/wp-content\/uploads\/2023\/05\/Screenshot-2023-05-07-at-9.22.06-PM-624x386.png 624w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Wrapping Up<\/strong><\/span><\/p>\n<p>Above are a few different plot options we have with mixed model outputs. I&#8217;m not sure what James was after or what he had in mind because he left the question very wide open. Hopefully this article provides some useful ideas for your own mixed model plotting. If there are other things you are hoping to see or have other ideas of things to plot from the mixed model output, feel free to reach out!<\/p>\n<p>The complete code for this article is available on my <strong><span style=\"color: #0000ff;\"><a style=\"color: #0000ff;\" href=\"https:\/\/github.com\/pw2\/Mixed-Models\/blob\/main\/Plotting%20Mixed%20Models.R\">GITHUB page<\/a><\/span><\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This weekend I posted two new blog articles about building reports that contained both data tables and plots on the same canvas (see HERE and HERE). As a follow up, James Baker asked if I could do some plotting of mixed model outputs. That got me thinking, I&#8217;ve done a few blog tutorials on mixed [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[47,43],"tags":[],"class_list":["post-3056","post","type-post","status-publish","format-standard","hentry","category-model-building-in-r","category-sports-analytics"],"_links":{"self":[{"href":"https:\/\/optimumsportsperformance.com\/blog\/wp-json\/wp\/v2\/posts\/3056","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/optimumsportsperformance.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/optimumsportsperformance.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/optimumsportsperformance.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/optimumsportsperformance.com\/blog\/wp-json\/wp\/v2\/comments?post=3056"}],"version-history":[{"count":2,"href":"https:\/\/optimumsportsperformance.com\/blog\/wp-json\/wp\/v2\/posts\/3056\/revisions"}],"predecessor-version":[{"id":3067,"href":"https:\/\/optimumsportsperformance.com\/blog\/wp-json\/wp\/v2\/posts\/3056\/revisions\/3067"}],"wp:attachment":[{"href":"https:\/\/optimumsportsperformance.com\/blog\/wp-json\/wp\/v2\/media?parent=3056"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/optimumsportsperformance.com\/blog\/wp-json\/wp\/v2\/categories?post=3056"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/optimumsportsperformance.com\/blog\/wp-json\/wp\/v2\/tags?post=3056"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}