在 knitr 中投影

Drop shadow in knitr

我正在混合使用 knitr、beamer 和 xelatex 来为讲座制作一些幻灯片。我希望看到我的人物投下阴影,以使我的演示文稿更花哨。

我发现 this great way 可以从常规图形中删除阴影,但我无法让它在 knitr 块中工作。

你们知道我该如何解决这个问题吗?

使用 chunk option fig.show = "hide" 您可以防止 knitr 将生成的图形包含到您的文档中。这允许您使用您喜欢的任何标记手动包含图形。

请注意,默认情况下图形存储在目录 figure 中,文件名遵循模式 chunkname-figurenumber,例如mychunk 中的第二个图形的文件名是 mychunk-1.pdf。 (参见上面链接的区块选项列表中的 fig.path。)

这给我们留下了最后一个陷阱:情节的背景颜色。

Depending on the graphics packages and devices you use, the background of plots might be transparent (e.g. tikz for base graphics) or white (e.g. ggplot2) by default. If you definitely want the background color to be always white for base graphics, you can set up a hook for the white option like this:

<<white-background,eval=FALSE>>=    
knit_hooks$set(white = function(before, options, envir) {if (before) par(bg = 'white')}) 

(引用自old version of the knitr graphics manual;我在当前版本中找不到它。)

如果你需要一个块钩子或者设置 par(bg = "white") 是否足够你取决于你生成的图表数量。如果您不知道如何使用 chunk hooks,请查看 this posting.

的末尾

不使用块钩子并修改 TEX 代码 from the answer that was linked in the question,以下代码使用 knitr 生成带阴影的图形:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{shadows,calc}

% code adapted from https://tex.stackexchange.com/a/11483/3954
% code then adapted from https://tex.stackexchange.com/a/81847/37118
%
% some parameters for customization
\def\shadowshift{3pt,-3pt}
\def\shadowradius{6pt}

\colorlet{innercolor}{black!60}
\colorlet{outercolor}{gray!05}

% this draws a shadow under a rectangle node
\newcommand\drawshadow[1]{
    \begin{pgfonlayer}{shadow}
        \shade[outercolor,inner color=innercolor,outer color=outercolor] ($(#1.south west)+(\shadowshift)+(\shadowradius/2,\shadowradius/2)$) circle (\shadowradius);
        \shade[outercolor,inner color=innercolor,outer color=outercolor] ($(#1.north west)+(\shadowshift)+(\shadowradius/2,-\shadowradius/2)$) circle (\shadowradius);
        \shade[outercolor,inner color=innercolor,outer color=outercolor] ($(#1.south east)+(\shadowshift)+(-\shadowradius/2,\shadowradius/2)$) circle (\shadowradius);
        \shade[outercolor,inner color=innercolor,outer color=outercolor] ($(#1.north east)+(\shadowshift)+(-\shadowradius/2,-\shadowradius/2)$) circle (\shadowradius);
        \shade[top color=innercolor,bottom color=outercolor] ($(#1.south west)+(\shadowshift)+(\shadowradius/2,-\shadowradius/2)$) rectangle ($(#1.south east)+(\shadowshift)+(-\shadowradius/2,\shadowradius/2)$);
        \shade[left color=innercolor,right color=outercolor] ($(#1.south east)+(\shadowshift)+(-\shadowradius/2,\shadowradius/2)$) rectangle ($(#1.north east)+(\shadowshift)+(\shadowradius/2,-\shadowradius/2)$);
        \shade[bottom color=innercolor,top color=outercolor] ($(#1.north west)+(\shadowshift)+(\shadowradius/2,-\shadowradius/2)$) rectangle ($(#1.north east)+(\shadowshift)+(-\shadowradius/2,\shadowradius/2)$);
        \shade[outercolor,right color=innercolor,left color=outercolor] ($(#1.south west)+(\shadowshift)+(-\shadowradius/2,\shadowradius/2)$) rectangle ($(#1.north west)+(\shadowshift)+(\shadowradius/2,-\shadowradius/2)$);
        \filldraw ($(#1.south west)+(\shadowshift)+(\shadowradius/2,\shadowradius/2)$) rectangle ($(#1.north east)+(\shadowshift)-(\shadowradius/2,\shadowradius/2)$);
    \end{pgfonlayer}
}

% create a shadow layer, so that we don't need to worry about overdrawing other things
\pgfdeclarelayer{shadow}
\pgfsetlayers{shadow,main}

\newsavebox\mybox
\newlength\mylen

\newcommand\shadowimage[2][]{%
\setbox0=\hbox{\includegraphics[#1]{#2}}
\setlength\mylen{\wd0}
\ifnum\mylen<\ht0
\setlength\mylen{\ht0}
\fi
\divide \mylen by 120
\def\shadowshift{\mylen,-\mylen}
\def\shadowradius{\the\dimexpr\mylen+\mylen+\mylen\relax}
\begin{tikzpicture}
\node[anchor=south west,inner sep=0] (image) at (0,0) {\includegraphics[#1]{#2}};
\drawshadow{image}
\end{tikzpicture}}

\begin{document}


<<myfigure, echo = FALSE, fig.show = "hide">>=
par(bg = "white")
plot(1)
@

\begin{frame}
\shadowimage[width=7cm]{figure/myfigure-1}
\end{frame}

\end{document}