Closed giabaio closed 3 years ago
Hi @giabaio ,
What tells you that cropping is not happening ? Do you have an error ? Is your file needed cropping ?
Without a reproducible example to run on our side it is difficult to know what is going on. Hooks are run by knitr, and xaringan will run knitr so I believe this will run any hook you define. Can you share an example for which you think this is not working as expected ?
Also did you compare with another format ? Is this something you observe is working with html_document
but not with xaringan::moon_reader()
Also pdfcrop
utility only apply on pdf files, and it needs to be available on the system, also with ghostscript
- but I think you would have seen warnings if you don't have that.
Thanks you for the complement
Thank you @cderv --- this is helpful. So: I know that cropping happens with other chunks producing images. So for instance, if I have set up this in a chunk at the beginning of my slides
# SET UP
# ... other commands
# This is a hack to insert 'alt-text' in images created by the R chunks
# source: https://ropensci.org/technotes/2020/04/23/rmd-learnings/
# NB: the 'alt-text' needs to be **'title'** attribute that gets included in the list 'opts'
# which is included as part of the set up in the chunk, for example
# ```{r echo=FALSE,opts=list(title="Alt-text",width="45%"...)}
# (see: https://www.computerhope.com/issues/ch001076.htm).
# Also, needs to specify the 'width' option (= what would normally be 'out.width') to ensure
# that the resulting HTML code to format the graph
knitr::knit_hooks$set(
plot = function(x, options) {
opts <- options$opts
paste0(
"<img src=",
'"', x, '" ',
if (!is.null(opts)) {
# Here include the styling for the graphs - this ensure it's centered
paste('style="display: block; margin: auto;"',
# And this "glues" the options passed by the user (including the 'alt-text')
glue::glue_collapse(glue::glue('{names(opts)}="{opts}"'),sep = " ")
)
},
">\n"
)
},
# This sets up a switch that allows to automatically crop the images generated by R
# https://bookdown.org/yihui/rmarkdown-cookbook/crop-plot.html
knitr::knit_hooks$set(crop = knitr::hook_pdfcrop)
)
# Defaults for figure size
# fig.retina=3 improves the quality of the resulting graph (https://arm.rbind.io/slides/xaringan.html#89)
knitr::opts_chunk$set(fig.width=10, fig.height=9, out.width="55%", fig.align='center', fig.retina=3, crop=TRUE)
a pure R
code eg
{r echo=FALSE,dev="tikz",fig.width=7,fig.height=6,opts=list(width="60%",title="INCLUDE TEXT HERE")}
set.seed(14)
x=seq(0,50,.1)
m=8
s=5
n=dnorm(x,m,s)
g=dgamma(x,shape=m^2/s^2,rate=m/s^2)
ln=dlnorm(x,lognPar(m,s)$mulog,lognPar(m,s)$sigmalog)
rg=range(n,g,ln)
plot(x,n,bty="l",xlab="",ylab="Density",ylim=rg,t="l",lwd=2)
points(x,g,bty="l",col="red",t="l",lwd=2)
points(x,ln,bty="l",col="blue",t="l",lwd=2)
legend("topright",c(paste0("Normal$(\\mu,\\sigma)$: mean=",m,", sd=",s,", median=",m),
paste0("Gamma$(\\alpha,\\beta)$: mean=",m,", sd=",s,", median=",format(median(rgamma(10000,shape=m^2/s^2,rate=m/s^2)),
digits=3,nsmall=3)),
paste0("log-Normal$(\\eta,\\tau)$: mean=",m,", sd=",s,", median=",
format(median(rlnorm(10000,lognPar(m,s)$mulog,lognPar(m,s)$sigmalog)),digits=3,nsmall=3))),
col=c("black","red","blue"),bty="n",lty=1,lwd=rep(2,3),cex=1.1
)
mtext("$y$",1,line=2.5,cex=1.2)
text(20,.08,"$\\displaystyle\\alpha=\\frac{\\mu^2}{\\sigma^2},\\,\\beta=\\frac{\\mu}{\\sigma^2}$",cex=1.0,pos=4)
text(20,.068,"$\\displaystyle\\eta=\\log(\\mu)-\\frac{1}{2}\\log\\left(1+\\frac{\\sigma^2}{\\mu^2}\\right),\\,\\tau=\\log\\left(1+\\frac{\\sigma^2}{\\mu^2}\\right)$",cex=1.0,pos=4)
does crop the image. (I do have pdfcrop
installed and I can check the resulting pdf and then png files with and without the command above and the image is indeed cropped if I turn the switch on).
The issue is when I run the following code on another slide
{r bayesian_hta1,engine='tikz', echo=F, out.width="85%",crop = TRUE,opts=list(width="75%",title="INSERT TEXT HERE"),eval=FALSE}
# This uses pure tikz to create an image. The margins are too large and I'd like to crop the pic so that it doesn't take up unnecessary space in the slide...
\newcommand\blue{\color{blue}}
\begin{tikzpicture}
\draw(-3,0) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{9}{10}\selectfont,minimum width=.2cm,minimum height=.1cm,color=white](1){$c_i$};
\draw(-3,1) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{9}{10}\selectfont,minimum width=.2cm,minimum height=.1cm,color=white](2){$\phi_{ic}$};
\draw(-4,1) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{9}{10}\selectfont,minimum width=.2cm,minimum height=.1cm,color=white](3){$\boldsymbol\tau_{c}$};
\draw(-3,2) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{9}{10}\selectfont,minimum width=.2cm,minimum height=.1cm,color=white](4){$\mu_c$};
\draw(-4,2) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{9}{10}\selectfont,minimum width=.2cm,minimum height=.1cm,color=white](5){$[\ldots]$};
\draw(-1,0) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{9}{10}\selectfont,minimum width=.2cm,minimum height=.1cm](6){$e_i$};
\draw(0,1) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{9}{10}\selectfont,minimum width=.2cm,minimum height=.1cm](7){$\phi_{ie}$};
\draw(-0,0) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{9}{10}\selectfont,minimum width=.2cm,minimum height=.1cm](8){$\boldsymbol\tau_{e}$};
\draw(-1,2) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{9}{10}\selectfont,minimum width=.2cm,minimum height=.1cm](9){$\mu_e$};
\draw(-0,2) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{9}{10}\selectfont,minimum width=.2cm,minimum height=.1cm](10){$[\ldots]$};
\draw(-2.25,2) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{9}{10}\selectfont,minimum width=.2cm,minimum height=.1cm,color=white](11){$\beta_1$};
\draw [->,>=latex,shorten >=-2pt,shorten <=-4pt,auto,node distance=0pt,thin] (7.230) -- (6.60);
\draw [->,>=latex,shorten >=-2pt,auto,shorten <=-4pt,node distance=.0pt,thin] (8.west) -- (6.east);
\draw [->,>=latex,shorten >=-2pt,shorten <=-4pt,auto,node distance=.0pt,thin] (9.320) -- (7.130);
\draw [->,>=latex,shorten >=-4pt,shorten <=-6pt,auto,node distance=.0pt,thin,dotted] (10.south) -- (7.north);
\draw[rounded corners=15pt,dashed,thick,color=blue] (-1.7,-.55) rectangle ++ (2.35,3.1) node[xshift=-1.1cm, yshift=0.15cm]{\fontsize{6}{7}\selectfont \sffamily Marginal model for $e$};
\draw(2.2,2) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{7}{8}\selectfont,minimum width=.2cm,minimum height=.1cm](11){$\blue e_{i} \sim p(e\mid \phi_{ei},\boldsymbol\tau_e)$};
\draw(2.2,1.6) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{7}{8}\selectfont,minimum width=.2cm,minimum height=.1cm](11){$\blue g_e(\phi_{ei}) = \alpha_0 \, [+\ldots]$};
\draw(2.2,1.2) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{7}{8}\selectfont,minimum width=.2cm,minimum height=.1cm](11){$\blue \mu_e = g_e^{-1}(\alpha_0)$};
\draw(-7.45,2) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{7}{8}\selectfont,minimum width=.2cm,minimum height=.1cm,color=white](11){$c_{i} \sim p(c\mid e,\phi_{ci},\boldsymbol\tau_c)$};
\draw(-6.63,1.6) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{7}{8}\selectfont,minimum width=.2cm,minimum height=.1cm,color=white](11){$g_c(\phi_{ci}) = \beta_0 + \beta_1(e_{i}-\mu_e)\, [+\ldots]$};
\draw(-7.8,1.2) node[align=center,circle,draw=none,fill=none,font=\sffamily\fontsize{7}{8}\selectfont,minimum width=.2cm,minimum height=.1cm,color=white](11){$\mu_c=g_c^{-1}(\beta_0)$};
\draw(2.1,.5) node[align=left,circle,draw=none,fill=none,font=\sffamily\fontsize{7}{8}\selectfont,minimum width=.2cm,minimum height=.1cm](11){\blue $\phi_{ei}=$ location};
\draw(2.1,.25) node[align=left,circle,draw=none,fill=none,font=\sffamily\fontsize{7}{8}\selectfont,minimum width=.2cm,minimum height=.1cm](11){\blue $\boldsymbol\tau_{e}=$ ancillary};
\draw(-7.3,.5) node[align=left,circle,draw=none,fill=none,font=\sffamily\fontsize{7}{8}\selectfont,minimum width=.2cm,minimum height=.1cm,color=white](11){$\phi_{ci}=$ location};
\draw(-7.3,.25) node[align=left,circle,draw=none,fill=none,font=\sffamily\fontsize{7}{8}\selectfont,minimum width=.2cm,minimum height=.1cm,color=white](11){$\boldsymbol\tau_c=$ ancillary};
\end{tikzpicture}
Now the code works fine and it makes up the pdf and then png file with the desired tikz image. But in this case, the cropping does not happen --- the image still has a large margin, especially at the top. Incidentally, you can crop this (which I did manually with pdfcrop
on the resulting pdf file) and then also crop the png (a simple line of mogrify
can do that of course). But for some reason (which may well be due to the fact that I don't fully know what I'm doing under the rmarkdown
/xaringan
hood...) it fails to do so automatically.
Anyway --- I don't think it's a big deal: in reality, I think, while not very elegant, it's probably more efficient to create the image once (using the tikz graph and outputting on a pdf/png), manually (well, I can automate this with a script...) cropping the two images (pdf and png) and then simply include the graph in the slides (rather than having R
process the tikz code every time I recompile the slides)... But I thought I'd mention this as it may be an interesting problem?
Does this make sense?
Thanks for your help, Gianluca
Thanks for the explanation.
In fact, I don't think this is a xaringan issue specifically. I am just not sure you can use this knitr::hook_pdfcrop
with 'tikz' engine currently (on any non R engine maybe).
This is a knitr behavior currently : When running the example using engine = 'tikz'
, plot paths are not registered so the hook won't have access to the plot file path to run pdfcrop
on. This would be a feature request in knitr if that is possible to do (I need to look deeper)
You can try in a .Rmd
file to knit, with rmarkdown and html_document
, you'll observe the same behavior.
Thanks for the report.
I opened an issue in knitr, and so will close this one. Thanks!
Thank you! This is very helpful!
As usual, I may be missing something obvious here - in which case, apologies in advance!
So: I've got a
xaringan
presentation, for which I've created my css file and I have a R file with the setup. This includes the code(I need the former to be able to add a 'title', which shows up as alt_text for a given image). Then I've added the
pdfcrop
option to be able to (as I understand it!) crop automatically the figures produced when compiling theR
code.The former option works, but the latter doesn't seem to - in other words, the resulting figures are not cropped. Is there some kind of idiosyncrasy between
xaringan
andpdfcrop
? Or should this work straight out of the box and I'm messing it up? I am adding the optioncrop=TRUE
in the chunk set up, eg:(NB: yes. I intend to use this on a chunk that's executing a tikz picture. Could this also be a problem?)...
And I've also tried to add the option
crop=TRUE
inside theopts
list, but to no avail...Thanks for the help! Gianluca