Using knitr with multiple languages and integrating non-standard graphical elements (as animations that auto-play in PDF output) requires special arrangements. Here are the things I've learnt:
For R chunks, using
dev="tikz"works fine, but for python chunks
dev="png"is required.
Normally, fig.width
and fig.height
would set the size of the inlined graph, like this:
<<pymc-plot-diagnostics, engine="python", dev = "png", dpi = 200, cache = TRUE, fig.cap = "Traces for the chains. This is based on a too small sample.", fig.width = 4, fig.height = 6>>= az.plot_trace(fitted, compact=True, chain_prop="color", figsize=(8, 12), backend_kwargs={"constrained_layout": True}); plt.show() @
But with the png device, that would result in this latex code:
\includegraphics[width=\maxwidth]{figure/pymc-plot-diagnostics-1}, which ignores
fig.width
. To set the width, use out.width
instead:
<<pymc-plot-diagnostics, engine="python", dev = "png", dpi = 200, cache = TRUE, fig.cap = "Traces for the chains. This is based on a too small sample.", out.width = "0.6\\linewidth">>= az.plot_trace(fitted, compact=True, chain_prop="color", figsize=(8, 12), backend_kwargs={"constrained_layout": True}); plt.show() @
To set the relative font size, modify figsize
. I needed to decrease the fontsize, which I achieved by increasing the figsize, from (8, 12)
to (10, 14)
<<pymc-plot-diagnostics-2, engine="python", dev="png", fig.cap = "Traces for the chains from the object that combined two sets of two chains each with 500 draws per chain. The number of chains is now four and they still contain 500 samples each.", cache = TRUE, out.width = "0.75\\linewidth">>= fig = az.plot_trace(fitted_all, compact=True, chain_prop="color", figsize=(10, 14), backend_kwargs={"constrained_layout": True}) plt.show() @
highlight
is a program required to format python chunks. To install on Debian GNU/Linux,
sudo apt-get install highlight
Some python chunks are not rendered correctly by default. For example, this chunk
<<pymc-plot-diagnostics, engine="python", dev = "png", cache = TRUE, fig.cap = "Traces for the chains. This is based on a too small sample.">>= az.plot_trace(fitted, compact=True, chain_prop='color') plt.show() @
rendered as
az.plot_trace(fitted, compact=True, chain_prop='color') plt.show()
until I added a ";" to hint to highlight
that it was two separate lines of python code.
Another way to achieve that is to turn off highlight
. Think of highlight
in the same way as you think of tidy
. The drawback of turning off highlight
is that you lose the color-coding.
Use the rgl
package to create the 3D animation, here a spinning cube with some data points in it, save it as a GIF-file in the current directory.
<<intro-data-3D, echo = FALSE>>= rgl::par3d(cex = 2.5, windowRect = c(0, 0, 1600, 1200)) rgl::plot3d(x=my.df$Salary, y=my.df$Experience, z=my.df$Salary, col="black", xlab = "Education", ylab = "Experience", zlab = "Salary", type ="s", radius = 0.5) rgl::play3d(rgl::spin3d(axis = c(0, 0, 1), rpm = 2), duration = 1.5) rgl::movie3d( movie="TwoIndependentVars", rgl::spin3d(axis = c(0, 0, 1), rpm = 3), duration = 10, fps = 10, dir = getwd(), type = "gif", clean = TRUE, webshot = FALSE ) @
Use the magick
package to convert it to a PDF-animation.
<<intro-to.pdf.magick, echo = FALSE>>= library(magick) ## Read the GIF file gif <- image_read("TwoIndependentVars.gif") ## Coalesce the GIF frames to ensure consistent size gif_frames <- image_coalesce(gif) ## Write the frames to a PDF image_write(gif_frames, path = "TwoIndependentVars_frame.pdf", format = "pdf") @
Include the PDF into the final PDF with animategraphics
, which is part of the package animate
.
\begin{figure}[ht!] \centering \animategraphics[scale=0.15, loop, autoplay]{10}{TwoIndependentVars_frame}{}{} \caption{The observations in a 3D plot. The independent variable is represented by the up-down axis, and the independent variables in the plane in the bottom of the cube.} \label{fig:data-in-3D} \end{figure}