首页 文章

ggplot和pgfSweave的问题

提问于
浏览
6

我不久前开始使用Sweave . 但是,像大多数人一样,我很快遇到一个主要问题:速度 . 扫描大型文档需要很长时间才能运行,这使得高效工作非常具有挑战性 . 使用cacheSweave可以加速数据处理 . 但是,情节 - 特别是ggplot;) - 渲染时间仍然太长 . 这是我想要使用pgfSweave的方式 .

经过许多小时,我终于成功地用Eclipse / StatET / Texlipse Build 了一个工作系统 . 然后,我想将现有的报告转换为与pgfSweave一起使用,并且有一个惊喜:我的大多数ggplots似乎都不再起作用了 . 以下示例在控制台和Sweave中完美运行:

pl <- ggplot(plot_info,aes(elevation,area))
pl <- pl + geom_point(aes(colour=que_id))
print(pl)

然而,使用pgfSweave运行它,我收到此错误:

Error in if (width > 0) { : missing value where TRUE/FALSE needed
In addition: Warning message:
In if (width > 0) { :
  the condition has length > 1 and only the first element will be used
Error in driver$runcode(drobj, chunk, chunkopts) : 
  Error in if (width > 0) { : missing value where TRUE/FALSE needed

当我从geom_point中删除aes(...)时,该图与pgfSweave完美配合 .

pl <- ggplot(plot_info,aes(elevation,area))
pl <- pl + geom_point()
print(pl)

编辑:我对问题进行了更多调查,可以将问题减少到tikz-device .

这很好用:

quartz()
pl <- ggplot(plot_info,aes(elevation,area))
pl <- pl + geom_point(aes(colour=que_id))
print(pl)

这给出了上述错误:

tikz( 'myPlot.tex',standAlone = T )
pl <- ggplot(plot_info,aes(elevation,area))
pl <- pl + geom_point(aes(colour=que_id))
print(pl)
dev.off()

这也很好用:

tikz( 'myPlot.tex',standAlone = T )
pl <- ggplot(plot_info,aes(elevation,area))
pl <- pl + geom_point()
print(pl)
dev.off()

我可以用5种不同的ggplots重复这个 . 在映射中不使用颜色(或大小,alpha,...)时,它适用于tikz .

Q1:有没有人对这种行为有任何解释?

此外,非绘图代码块的缓存不能很好地工作 . 使用Sweave时,以下代码块完全没有时间 . 使用pgfSweave,大约需要10秒 .

<<plot.opts,echo=FALSE,results=hide,cache=TRUE>>=
#colour and plot options are globally set
pal1 <- brewer.pal(8,"Set1")
pal_seq <- brewer.pal(8,"YlOrRd")
pal_seq <- c("steelblue1","tomato2")
opt1 <- opts(panel.grid.major = theme_line(colour = "white"),panel.grid.minor = theme_line(colour = "white"))
sca_fill_cont_opt <- scale_fill_continuous(low="steelblue1", high="tomato2")
ory <- geom_hline(yintercept=0,alpha=0.4,linetype=2) 
orx <- geom_vline(xintercept=0,alpha=0.4,linetype=2)
ts1 <- 2.3
ts2 <- 2.5
ts3 <- 2.8
ps1 <- 6
offset_x <- function(x,y) 0.15*x/pmax(abs(x),abs(y))
offset_y <- function(x,y) 0.05*y/pmax(abs(x),abs(y))
plot_size <- 50*50

这似乎是一个非常奇怪的行为,因为只有一些变量被设置供以后使用 .

Q2:有人对此有任何解释吗?

Q3:更一般地说,我想问一下是否有人成功使用pgfSweave?成功的意思是所有在Sweave中工作的东西也可以在pgfSweave中工作,还有漂亮字体和提高速度的额外好处 . ;)

非常感谢您的回复!

3 回答

  • 4

    Q1:有没有人对此行为有任何解释?

    这些是tikzDevice在尝试构建绘图时出错的三个原因:

    • 当您添加创建图例的美学映射(例如 aes(colour=que_id) )时,ggplot2将使用变量名称作为图例的 Headers - 在本例中为que_id .

    • tikzDevice将所有字符串(例如图例 Headers )传递给LaTeX进行排版 .

    • 在LaTeX中,下划线字符 _ 用于表示下标 . 如果在数学模式之外使用下划线,则会导致错误 .

    当tikzDevice尝试计算图例 Headers "que_id"的高度和宽度时,它会将字符串传递给LaTeX进行排版,并期望LaTeX返回字符串的宽度和高度 . LaTeX遇到错误,因为在mathmode之外的字符串中使用了未转义的下划线 . tikzDevice接收字符串宽度的 NULL 而不是导致 if (width > 0) 检查失败的数字 .

    Ways to avoid the problem

    • 通过添加色标来指定要使用的图例 Headers :
    p1 <- ggplot(plot_info, aes(elevation, area))
    p1 <- p1 + geom_point(aes(colour=que_id))
    
    
    # Add a name that is easier for humans to read than the variable name
    p1 <- p1 + scale_colour_brewer(name="Que ID")
    
    
    # Or, replace the underscore with the appropriate LaTeX escape sequence
    p1 <- p1 + scale_colour_brewer(name="que\\textunderscore id")
    
    • 使用tikzDevice 0.5.0中引入的字符串清理功能(但在0.5.2之前已被破坏) . 目前,字符串清理只会转义以下字符: %${}^ 默认情况下 . 但是,您可以通过 tikzSanitizeCharacterstikzReplacementCharacters 选项指定其他替换对:
    # Add underscores to the sanitization list
    options(tikzSanitizeCharacters = c('%','$','}','{','^', '_'))
    options(tikzReplacementCharacters = c('\\%','\\$','\\}','\\{',
      '\\^{}', '\\textunderscore'))
    
    
    # Turn on string sanitization when starting the plotting device
    tikz('myPlot.tex', standAlone = TRUE, sanitize = TRUE)
    print(p1)
    dev.off()
    

    我们将在接下来的几周内发布tikzDevice的0.5.3版本,以便解决由于R处理方式的变化而出现的一些恼人的警告消息 system() . 我将在下一个版本中添加以下更改:

    • widthNULL 时更好的警告消息,表示情节文字可能有问题 .

    • 将下划线和一些其他字符添加到字符串清理程序查找的默认字符集中 .

    希望这可以帮助!

  • 3

    Q2:我是pgfsweave的维护者 .

    以下是我跑的测试结果:

    time R CMD Sweave time-test.Rnw 
    
    real    0m1.133s
    user    0m1.068s
    sys     0m0.054s
    
    time R CMD pgfsweave time-test.Rnw 
    
    real    0m2.941s
    user    0m2.413s
    sys     0m0.364s
    
    time R CMD pgfsweave time-test.Rnw 
    
    real    0m2.457s
    user    0m2.112s
    sys     0m0.283s
    

    我相信时差有两个原因,但要完全验证它们需要更多的工作:

    • pgfSweave进行了大量的检查和双重检查,以确保它不会重做昂贵的计算 . 目标是使在文档中进行更昂贵的计算和绘图变得可行 . 在这种情况下,"expensive"的规模远远超过额外的第二或第二次检查 .

    作为缓存的示例,请考虑以下测试文件看到缓存的真正好处:

    \documentclass{article}
    
    \begin{document}
    
    <<plot.opts,cache=TRUE>>=
    x <- Sys.sleep(10)
    @
    
    \end{document}
    

    结果如下:

    time R CMD Sweave time-test2.Rnw 
    
    real    0m10.334s
    user    0m0.283s
    sys     0m0.047s
    
    time R CMD pgfsweave time-test2.Rnw 
    
    real    0m12.032s
    user    0m1.356s
    sys     0m0.349s
    
    time R CMD pgfsweave time-test2.Rnw 
    
    real    0m1.423s
    user    0m1.121s
    sys     0m0.266s
    
    • Sweave在R 2.12中经历了一些变化 . 这些变化可能加快了代码块评估的过程,并为这些较小的计算留下了pgfSweave . 值得研究

    Q3:我自己一直使用pgfSweave来完成自己的工作 . R 2.12中的Sweave已经发生了一些变化,这些变化导致了pgfSweave的一些小问题,但是即将推出的新版本可以解决所有问题 . github上的开发版本(https://github.com/cameronbracken/pgfSweave)已经有了变化 . 如果您遇到其他问题,我很乐意为您提供帮助 .

  • 1

    Q2:你在 Headers 和选项 external=TRUE 中使用_2566836用于图形块吗?我在pgfSweave插图中找到更多背景信息 .

    Q3:一切正常,我就像你一样使用Windows Eclipse / StatEt / Texlipse .

相关问题