2012-09-04 26 views
10

我已经搜索过,谷歌搜索,阅读?pdf,并找出了可以保存一个PDF格式的图形的可能性与层可以swiethed和在pdf查看器边缘关闭。我正在谈论的一个例子是USGS四地形地图,它可以下载为多层的pdf格式,如this(压缩的pdf)。如何在R中保存一个分层的pdf(通过Sweave?)

在PDF()帮助文件下一句听起来很可怕,但我也想检查我没有曲解它:

The R graphics model does not distinguish graphics objects at the level 
of the driver interface. 

我曾经能够保存分层PDF在Illustrator中,但不再有这个程序在我手中。也许有人可以从R内想到一个解决方法?我使用地图的数据是大的,但这里有一个玩具例子:

pdf("2objects.pdf") 
plot(NULL, type = "n",xlim = c(0,1),ylim = c(0,1)) 
rect(0,.7,.7,0,border = "blue",lwd=2) 
rect(.3,1,1,.3,border = "red",lty=2,lwd=2) 
dev.off() 

它看起来像这样(这是一个PNG,但上述会给一个pdf) enter image description here

我会就像能够将红色和蓝色框作为可见度的图层一样,可以在PDF查看器中打开和关闭。

非常感谢!

编辑:找到thread in R-help(re:@mnel),它看起来不可能。我仍然会留下这个问题,以防有人提出了一个漂亮的R-tastic解决方案。

编辑(2012年9月5日):我尝试通过Sweave进行此操作,并使用已发布的解决方法here取得了部分成功。这种方法产生一个带有'图层'的pdf,可以使用图像下面的超链接文本打开和关闭。它使用'动画'欺骗来做到这一点。尽管它还不是我最终的期望结果,但它的优势在于不依赖于特定的pdf查看器。我仍然会等待,看看是否有人在Sweave文档中发布图层,也就是OCG,然后我可以将其自动化。

编辑(2012年9月13日):我使用上面提到的代码发布了一个答案,我能够在更复杂的现实世界中使用它,而且不会在美国境内覆盖不同行政和统计界限的代码进行更改。在这种情况下,我刚刚命名了不同的地图叠加层layer-0.pdflayer-1.pdf等,并且它没有错误地工作。我仍然希望最终有更好的东西出现在这里。

感谢所有为你评论

+1

你也许能得到这个,如果你使用['tikzDevice'(http://cran.r-project.org/src/contrib/Archive/tikzDevice/)工作,可以配置'tikz '或'pgf'给你一个包含图层的pdf。不幸的是,这个软件包已经存档了,但它确实生成了漂亮的图形(或者至少在2年前使用过的时候) – mnel

+0

谢谢@mnel,我现在通过Sweave尝试了这一点,如果我想出任何东西。 –

+0

我不知道ImageMagick是否可以使用两个独立的PDF分层? – Aaron

回答

1

我能够通过ggplot实现这一目标。

library(ggplot2) 
df <- data.frame(x = c(1,10), y = c(20,40), class = 1:2) 
layered_plot <- ggplot(df, aes(xmin = x, xmax = x + 1, ymin = y, ymax = y + 2, fill = class)) + 
geom_rect() + 
opts(legend.position = "none") 
# Now save this as pdf 
ggsave(layered_plot, file="p1.pdf") 

enter image description here

(这仅仅是png版本为了说明,但是当我在Illustrator打开pdf,根据需要我可以关闭各个层)。

enter image description here

+0

这可能是Illustrator的一个特点?似乎在导入PDF时,Illustrator将所有矢量元素分解为单个对象。我希望有一个解决方案,可以在避开Illustrator的情况下为一个盒子和另一个图层创建一个图层。虽然谢谢! –

+0

不知道这是否是一个插画问题。但是,如果你只需关掉一个或两个元素,就可以正常工作。你也可以通过拖拽一个方框并敲击组来快速分组元素(比如坐标轴)。这将有助于减少项目数量。 – Maiasaura

+0

如何用'.svg'扩展名保存文件?这将保留图层(类似地),但也完全绕过Illustrator(如果您有另一个免费程序可以打开)。 – Maiasaura

1

看起来像(texanimation答案是我能想出现在最好的。以下.Rnw文件将在中间创建一个带有数字的pdf文件,并在其下方创建2个文本超链接,从而独立切换红色和蓝色框的可见性。我发现使这项工作的Tex代码here。我还没有看过@亚伦的ocgtools建议,但会到达那里。非常感谢您的建议!

\documentclass{article} 
%----------------------------------------------------------------%\ 
\usepackage[OT1]{fontenc} 
\usepackage{Sweave} 
\usepackage{animate} 
\usepackage{hyperref} 
\usepackage[margin=0.4in]{geometry} 
%----------------------------------------------------------------% 

\makeatletter 
% command to create a toggle link 
\newcommand{\ShowHideLayer}[3]{% 
    % #1: anim No. (zero-based), 
    % #2: layer No. (zero-based), 
    % #3: link text 
    \leavevmode% 
    \pdfstartlink user { 
    /Subtype /Link 
    /Border [\@pdfborder]% 
    /A << 
     /S/JavaScript 
     /JS (
     \if at [email protected]% 
      if(a#1.fr[#2].state==true){ 
      a#1.fr[#2].state=false; 
      }else{ 
      a#1.fr[#2].state=true; 
      } 
     \else 
      if (a#1.fr[#2].display==display.visible){ 
      a#1.fr[#2].display=display.hidden; 
      }else{ 
      a#1.fr[#2].display=display.visible; 
      } 
      this.dirty=false; 
     \fi 
    ) 
    >> 
    }#3% 
    \pdfendlink% 
} 

% command to create a link to show/hide all layers 
\newcommand{\ShowHideAll}[2]{% 
    % #1: anim No. (zero-based), 
    % #2: link text 
    \leavevmode% 
    \pdfstartlink user { 
    /Subtype /Link 
    /Border [\@pdfborder]% 
    /A << 
     /S/JavaScript 
     /JS (
     var countvisible=0; 
     for(var i in a#1.fr){ 
      \if at [email protected] 
      if(a#1.fr[i].state==true){countvisible++;} 
      \else 
      if (a#1.fr[i].display==display.visible){countvisible++;} 
      \fi 
     } 
     if(countvisible){ 
      for(var i in a#1.fr){ 
      \if at [email protected] 
       a#1.fr[i].state=false; 
      \else 
       a#1.fr[i].display=display.hidden; 
       this.dirty=false; 
      \fi 
      } 
     } 
     else{ 
      for(var i in a#1.fr){ 
      \if at [email protected] 
       a#1.fr[i].state=true; 
      \else 
       a#1.fr[i].display=display.visible; 
       this.dirty=false; 
      \fi 
      } 
     } 
    ) 
    >> 
    }#2% 
    \pdfendlink% 
} 
\makeatother 

\begin{document} 

% heres the R-making of the plots, saved to working directory, 
% which should be the folder containing this .Rnw file 
% 3 versions of the same plot, one for each layer 
<<echo = FALSE, hide = TRUE>>= 
pdf("layer-0.pdf") 
plot(NULL, type = "n", xlim = c(0, 1), ylim = c(0, 1), xlab = "", ylab = "") 
dev.off() 

pdf("layer-1.pdf") 
plot(NULL, type = "n", xlim = c(0, 1), ylim = c(0, 1), axes = FALSE, xlab = "", ylab = "") 
rect(0, .7, .7, 0, border = "blue", lwd = 2) 
dev.off() 

pdf("layer-2.pdf") 
plot(NULL, type = "n", xlim = c(0, 1), ylim = c(0, 1), axes = FALSE, xlab = "", ylab = "") 
rect(.3, 1, 1, .3, border = "red", lty = 2, lwd = 2) 
dev.off() 
@ 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\begin{center} 
    %animated layer-set No. 0 
    %           v-- frame rate ignored 
    \animategraphics[width=1\linewidth,step]{1}{layer-}{0}{2} 

    \ShowHideLayer{0}{1}{toggle red box}\\ 
    \ShowHideLayer{0}{2}{toggle blue box}\\ 
\end{center} 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\end{document}