Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make fig.width and out.width consistent with knitr?

Tags:

r

latex

knitr

tikz

I have recently discovered knitr and I mainly use it to produce plots with dev=tikz to get a Latex typesetting easily. However I don't understand how to set chunk options fig.width and out.width with consistency.

I mean, I know that the first one is an R option while the second one is the latex option coming with \includegraphics but it seems like if fig.width is too large compared to out.width then the lines are very thin because latex shrink the picture. In the other hand if it's too small then latex streches it and everything is too big.

Basically I'd like too have a setting in wich I only choose the out.widthand then the thickness of the lines and texts is consistent with the text size of the document.

I include a MWE illustrating my problem. Also I have set fig.height in the first example otherwise the picture was then bigger than the page, I don't really understand this as well.

Any help is warmly welcome !

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage[T1]{fontenc}
\usepackage{graphicx}

<<setup, include=FALSE, cache=FALSE>>=
  library(knitr)
  options(formatR.arrow=TRUE,width=50)
  opts_chunk$set(fig.path='figure/graphics-', 
                 cache.path='cache/graphics-', 
                 fig.align='center', 
                 dev='tikz')
@

\begin{document}
\begin{figure}[!ht]
    <<fig_1,fig.width=2,  fig.height = 3,out.width = '\\textwidth',echo=FALSE>>=
    x = seq(1,3,l=100)
    plot(x,cos(x), type ="l", xlab = "x", ylab = "y")
    @
\end{figure}
\begin{figure}[!ht]
<<fig_2,fig.width=10,  out.width = '\\textwidth',echo=FALSE>>=
    x = seq(1,3,l=100)
    plot(x,cos(x), type ="l", xlab = "x", ylab = "y")
    @
\end{figure}

\end{document}
like image 773
ClementWalter Avatar asked Apr 15 '15 18:04

ClementWalter


1 Answers

Basically NO resizing should be made after the tikzpicture has been created, because it will lose consistency with text style. As a matter of fact, when chunk option cache=FALSE is set, then out.width has no effect because no pdf output is created. Hence one has to specify exact measures in inches for fig.widthand fig.height for each chunk.

After some research both on stackoverflow and in Knitr websites, I have found a trick to have almost the same user experience, ie that I don't want to care about real sizes but only think relatively to \textwidth and other Latex variables:

  • in the setup chunk, define R variables with explicit name (such as paperwidth, textwidth corresponding to the Latex one in inches, eg an A4 paper is (w,h) = (8.3, 11.7).
  • in each chunk with a plot, you can then use fig.width = 0.5*paperwidthfor example

Here is a MWE:

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{tikz}
<<setup, include=FALSE, cache=FALSE>>=
  library(knitr)
  options(formatR.arrow=TRUE,width=50)
  opts_chunk$set(fig.path='figure/graphics-', 
                 cache.path='cache/graphics-', 
                 fig.align='center',
                 dev='tikz',
                 external=TRUE,
                 echo=FALSE
                )
  a4width<- 8.3
  a4height<- 11.7
@

\begin{document}
\begin{figure}[!ht]
\centering
<<fig_1, fig.width = 0.4*a4width, fig.height = 0.2*a4height>>=
    x = seq(1,3,l=100)
    plot(x,cos(x), type ="l", xlab = "x", ylab = "y")
@

<<fig_2, fig.width = 0.2*a4width, fig.height = 0.5*a4height>>=
    x = seq(1,3,l=100)
    plot(x,cos(x), type ="l", xlab = "x", ylab = "y")
@

\caption{Test figure}
\end{figure}
\end{document}
like image 177
ClementWalter Avatar answered Oct 13 '22 00:10

ClementWalter