问题 1

问题 1

据我所知,R+tikDevice+LaTex+knitr 是从 R 中获取美观出版物的最有效方法,同时还能从 LaTeX 中获得最大程度的布局支持。

我现在正在使用 R+LaTex+knitr,但想让 LaTex 更好地管理字体大小、分辨率和图的比例,因此 tikzDevice 0.7.0 似乎是最佳选择。这里有一个与此有些相关的问题,但(我认为)在 knitr+tikzDevice 0.7.0 之前已经回答过了:有关图形尺寸的最佳实践

但是我尝试使用 tikzDevice 的所有尝试都使其变得更加复杂,所以我担心我错过了一些基本的东西。可能是关于图的大小定义的位置。

以下示例尝试绘制相同的内容三次:首先不使用 tikzDevice,然后使用两种 tikzDevice 方式。tikzDevice 幻灯片看起来不太好看,我可以通过操作宽度和高度来改善。但我已经在 LaTex 中定义了 column-with,所以我不需要做更多,对吧?

\documentclass{beamer}
\usepackage{tikz}

\begin{document}

\title{Beamer with 2+1 plots}
\author{Chris}

<<data.prep, include=FALSE>>=
library(ggplot2)
library(tikzDevice)
options(tikzDefaultEngine='xetex')
plot.data <- data.frame(days=c(1,2,3,4,5,6,7,8,9), price=c(2,3,4,3,5,6,5,7,8))
@

\begin{frame}{2+1 Plots (no Tikz)}
\begin{columns}
\begin{column}[t]{0.40\textwidth}
<<plot1, dev='pdf', fig.width=6, fig.height=5, dpi=144, echo=FALSE, message=FALSE, warning=FALSE, cache=FALSE>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
<<plot2, dev='pdf', fig.width=6, fig.height=5, dpi=144, echo=FALSE, message=FALSE, warning=FALSE, cache=FALSE>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
\end{column}
\begin{column}[t]{0.58\textwidth}
<<plot3, dev='pdf', fig.width=8, fig.height=9, dpi=144, echo=FALSE, message=FALSE, warning=FALSE, cache=FALSE>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
\end{column}
\end{columns}
\end{frame}

\begin{frame}{2+1 Plots (Tikz Attempt 1)}
\begin{columns}
\begin{column}[t]{0.40\textwidth}
<<plot4, results='hide', echo=FALSE, message=FALSE, warning=FALSE>>=
tikz("TikzAttempt1.tex",width=1.8,height=1.6)
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
dev.off()
@
\input{TikzAttempt1.tex}
<<plot5, results='hide', echo=FALSE, message=FALSE, warning=FALSE>>=
tikz("TikzAttempt2.tex",width=1.8,height=1.6)
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
dev.off()
@
\input{TikzAttempt2.tex}
\end{column}
\begin{column}[t]{0.58\textwidth}
<<plot6, results='hide', echo=FALSE, message=FALSE, warning=FALSE>>=
tikz("TikzAttempt3.tex",width=2,height=3)
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
dev.off()
@
\input{TikzAttempt3.tex}
\end{column}
\end{columns}
\end{frame}

\begin{frame}{2+1 Plots (Tikz Attempt 2)}
\begin{columns}
\begin{column}[t]{0.40\textwidth}
<<plot7, echo=FALSE, dev='tikz', fig.width=6, fig.height=5, out.width='.40\\paperwidth'>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
<<plot8, echo=FALSE, dev='tikz', fig.width=6, fig.height=5, out.width='.40\\paperwidth'>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
\end{column}
\begin{column}[t]{0.58\textwidth}
<<plot9, echo=FALSE, dev='tikz', fig.width=8, fig.height=9, out.width='.58\\paperwidth'>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
\end{column}
\end{columns}
\end{frame}

\end{document}

图的大小应该在哪里定义?在 chunk-definition 中?在 tikz-definition 中?在 LaTex input-definition 中?还是在 LaTex 中的 includegraphics-settings 中?

这两种 tikzDevice 方式哪一种最好使用?

我的演示文稿有许多带有情节的幻灯片,通常最终会得到 10MB 以上的 pdf 文件,希望通过 Tikz 可以降低文件大小。

由于字体原因,编译必须使用 XeLatex 完成。

Markdown 在这里不是一个选项,因为我需要做只有 LaTex 才能做的事情(未包含在示例中)。

答案1

这篇文章相当长。我将尝试回答你的两个主要问题。

抱歉,小说……

问题 1

以下示例尝试绘制同一件事三次:首先不使用 tikzDevice,然后使用两种 tikzDevice 方式。tikzDevice 幻灯片看起来不太好看,我可以通过操纵宽度和高度来改善。但我已经在 LaTex 中定义了 column-with,所以我不必做更多,或者?应该在哪里定义绘图的大小?在 chunk-definition 中?在 tikz-definition 中?在 LaTex input-definition 中?还是在 LaTex 中的 includegraphics-settings 中?

的作用beamer

让我们先从逆向思考开始。这个答案将首先清理你的“2+1 图(TiZ 尝试 2)”。第二次尝试效果不佳的原因很大程度上是由于beamer你的 LaTeX 代码,与 无关knitr

下面我将讨论字体大小knitr。(如果您希望立即转到那里,请向下滚动到标题“带有knitr”的字体大小。)

chunk选项knitr

首先,重要的是要了解chunk选项fig.heightfig.widthout.width的作用。根据 Yihui 的这些选项的文档fig.heightfig.width设置图形的高度和宽度R 以英寸来算。默认值为 7 英寸,传递给这些选项的值必须是数字。另一方面,out.width(和out.height)设置图形的宽度(和高度)就像最终输出文件中显示的那样。因此,这些值可以不同。如果这些尺寸不同,则最终输出文件中的图形将相应缩放。

现在,让我们看看你的第二个 Ti 的使用情况beamer及其环境Z 尝试。

LaTeX 宽度 &beamer

这需要和朋友们讨论一下\textwidth。@egreg回答有关图形尺寸的最佳实践对此提供了一些很好的讨论。简而言之,

\textwidth通常是文本区域的全局宽度[...]但是在或里面minipage\parbox将与、和\textwidth一起设置为给定的参数(它们将在形成组的或的末尾恢复为先前的值)。\hsize\columnwidth\linewidthminipage\parbox

我不熟悉beamer内部结构,但columns环境必须使用minipage或,\parbox因为环境\textwidth内部columns设置为列的总宽度,不是全局文本区域的总宽度。

因此,我们可以将 传递out.width='1\\textwidth'chunk,这将防止您的图表溢出页面。\paperwidth设置为整个页面的宽度,包括任何边距。这就是为什么您的图表在第二次尝试时似乎溢出页面的原因。

因此:

\documentclass{beamer}
\usepackage{tikz}

\begin{document}

\title{Beamer with 2+1 plots}
\author{Chris}

<<data.prep, include=FALSE>>=
library(ggplot2)
library(tikzDevice)
options(tikzDefaultEngine='xetex')
plot.data <- data.frame(days=c(1,2,3,4,5,6,7,8,9), price=c(2,3,4,3,5,6,5,7,8))
@

\begin{frame}{2+1 Plots (Tikz Attempt 3)}
\begin{columns}[onlytextwidth]
\begin{column}[t]{0.40\textwidth}
<<plot10, echo=FALSE, dev='tikz', fig.width=6, fig.height=5, out.width='1\\textwidth'>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
<<plot11, echo=FALSE, dev='tikz', fig.width=6, fig.height=5, out.width='1\\textwidth'>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
\end{column}
\begin{column}[t]{0.58\textwidth}
<<plot12, echo=FALSE, dev='tikz', fig.width=8, fig.height=9, out.width='1\\textwidth'>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
\end{column}
\end{columns}
\end{frame}

\end{document}

生成:

在此处输入图片描述

笔记:我已将选项传递onlytextwidthcolumns环境。请参阅@Werner 的讨论,他的回答Beamer 中带有图像和换行文本的多列

以一个图表为例,此幻灯片上最右边的图表由 制作而成,R宽度为 8 英寸,高度为 9 英寸。然后,LaTeX 获取此图形并将其缩放,使其宽度为1\textwidth,在本例中,它正好是最右边列的宽度。

现在,这些图表中的字体显然仍然很小,让我们看看可以做些什么来解决这个问题。

字体大小knitr

记录TikZDevice,我强烈建议您阅读它。不过,我会尝试将文档中的所有字体信息提炼为可用的格式。

计算字体大小

LaTeX 中的字体大小是根据基本字体大小指定的。因此,当您声明 时\documentlcass[10pt]{beamer},所有字体大小的变化都是相对于该基本字体大小计算的,并且不能通过类似以下方式轻松指定24pt。TiZ 通过缩放文本来处理这个问题;缩放因子是相对于基本字体大小计算的(参见文档了解更多信息)。

在谈论如何然而,要设置字体大小,我们必须真正了解缩放因子是如何计算的。

根据文档,缩放因子等于cex*( ps/ base font size),其中cexps设置在 中R

(我不太熟悉R这些是如何设置的。根据阅读TikZDevice文档,我随意猜测这些必须以某种方式通过ggplot2via来设置par。至少,?par如果你想尝试弄清楚的话,这似乎是开始的地方。但我真的不知道。)

但重点是,是分母base font size。因此,字体越小,base font size实际越大

使用设置字体大小knitr

那么我们如何设置这个基本字体大小呢?如果你使用第一种tikz()直接调用的方法,你可以在调用中设置它tikz()

tikz(<other arguments>, pointsize=10)

出于下面将要讨论的原因,我更喜欢您的其他方法。pointsize即使我们没有tikz()直接调用,我们仍然可以以这种方式设置。knitr提供了一个设备挂钩,因此我们可以将其用作dev.args=list(pointsize=10)选项chunk

以下是展示一些不同字体大小的 MWE:

\documentclass{beamer}
\usepackage{tikz}

\begin{document}

\title{Beamer with 2+1 plots}
\author{Chris}

<<data.prep, include=FALSE>>=
library(ggplot2)
library(tikzDevice)
options(tikzDefaultEngine='xetex')
plot.data <- data.frame(days=c(1,2,3,4,5,6,7,8,9), price=c(2,3,4,3,5,6,5,7,8))
@

\begin{frame}{2+1 Plots (Tikz Attempt 4)}
\begin{columns}[onlytextwidth]
\begin{column}[t]{0.40\textwidth}
Too big!
<<plot13, echo=FALSE, dev='tikz', dev.args=list(pointsize=0.9), fig.width=6, fig.height=5, out.width='1\\textwidth'>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
Pretty big!
<<plot14, echo=FALSE, dev='tikz', dev.args=list(pointsize=2), fig.width=6, fig.height=5, out.width='1\\textwidth'>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
\end{column}
\begin{column}[t]{0.58\textwidth}
Reasonable.
<<plot15, echo=FALSE, dev='tikz', dev.args=list(pointsize=6), fig.width=8, fig.height=9, out.width='1\\textwidth'>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
\end{column}
\end{columns}
\end{frame}

\end{document}

在此处输入图片描述

因此,您可以根据自己的喜好调整pointsize(设置所base font size使用的TikZDevice)。

问题2

这两种 tikzDevice 方式哪一种最好使用?

为了回答您的第二个问题,我更喜欢您使用的后一种方法。这是因为图表是作为其自己的 PDF 生成的,然后通过 LaTeX 输出呈现的\includegraphics。如果您将您的作品提交给需要单独 PDF 文件的出版商,这可能会很有利,例如,因为他们无法在自己的机器上编译您的图像。

另一方面,你以前的方法\input{}是 TiZ 代码。这样做的好处是,您可以轻松操作 TiZ 代码,无论出于何种原因。如果这是您需要做的事情,您可能希望阅读提供的bareBones方法TikZDevice。请参阅第 12-15 页文档

相关内容