代码之家  ›  专栏  ›  技术社区  ›  donodarazao

ggplot和pgfSweave的问题

  •  6
  • donodarazao  · 技术社区  · 14 年前

    我很久以前就开始用swave了。然而,和大多数人一样,我很快就遇到了一个大问题:速度。浏览一个大文档需要很长时间才能运行,这使得高效的工作相当具有挑战性。使用cacheswave可以大大加快数据处理速度。但是,绘图(尤其是ggplot;)-仍然需要很长时间才能渲染。 这就是我想用pgfSweave的方法。

    经过许多个小时,我终于成功地用Eclipse/StatET/Texlipse建立了一个工作系统。然后我想将现有的报告转换为PGFFWAVE使用,并有一个不好的惊喜:我的大部分GGTHOT似乎不再工作了。例如,以下图表在控制台和swave中工作得很好:

    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_点删除aes(…)时,该绘图与pgfSweave完美地结合在一起。

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

    编辑: 我对这个问题进行了更多的调查,可以把问题归结到tikz设备上。

    这很管用:

    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个不同的ggplot重复这个。当不在映射中使用颜色(或大小,alpha,…)时,它与tikz一起工作。

    有人对这种行为有什么解释吗?

    另外,非打印代码块的缓存也不能很好地工作。下面的代码块根本不占用swave的时间。用PGFFWAVE,大约需要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
    

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

    有人对此有什么解释吗?

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

    非常感谢您的回复!

    3 回复  |  直到 14 年前
        1
  •  4
  •   Sharpie    14 年前

    有人对这种行为有什么解释吗?

    以下是tikzDevice在构建图时出错的三个原因:

    • 当添加创建图例的美学映射时,例如 aes(colour=que_id) ,ggplot2将使用变量名作为图例的标题——在本例中为que_id。

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

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

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

    避免问题的方法

    1. 通过添加颜色比例指定要使用的图例标题:

      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")
      
    2. 使用tikzDevice 0.5.0中引入的字符串清理功能(但在0.5.2之前被破坏)。当前,字符串清理将只转义以下字符: % , $ , { , } ,和 ^ 默认情况下。但是,您可以通过 tikzSanitizeCharacters tikzReplacementCharacters 选项:

      # 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() . 我将在下一个版本中添加以下更改:

    • 更好的警告信息 width 无效的 表示绘图文本可能有问题。

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

    希望这有帮助!

        2
  •  3
  •   cameron.bracken    14 年前

    问题2:我是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做了大量的检查和重复检查,以确保它不会重做昂贵的计算。目标是使在文档中进行更昂贵的计算和绘图成为可能。在这种情况下,“昂贵”的规模远远超过额外的一两秒钟来做检查。

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

    \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
    
    • 瑞典在R 2.12中经历了一些变化。这些更改可能加快了代码块计算的进程,并留下pgfSweave用于这些较小的计算。值得一看

    问题3:我总是用pgfSweave来完成自己的工作。R 2.12版本中的swave有一些变化,导致pgfSweave出现了一些小问题,但是一个新版本即将发布,它可以修复所有问题。github上的开发版本( https://github.com/cameronbracken/pgfSweave )已经有了更改。如果你有其他问题,我很乐意帮忙。

        3
  •  1
  •   fabians    14 年前

    问题2:你用 \pgfrealjobname{<DOCUMENTNAME>} 在标题和选项中 external=TRUE 对于图形块? 我发现这会大大提高速度(不是第一次编译,而是在图形不变的情况下进行后续编译)。你会在pgfSweave的小插曲中找到更多的背景。

    问题3:一切对我来说都很好,我和你一样使用Windows+Eclipse/StatEt/Texlipse。