我想结合丰富的html小部件(主要是plot和networkD3),并有可能将它们安排为R中的网格中的绘图,将它们导出为pdf图形用于出版物。但是,如果我在R中创建一些html小部件对象,并尝试用gridExtra::grid.arrange()来排列它们(参见下面的最小示例),我会得到以下错误:
Error in gList(list(x = list(links = list(source = c(0, 0), target = c(1, :
only 'grobs' allowed in "gList"
我搜索了"将html小部件转换为grobs或plot",以便能够将它们排列在网格中,但无法找到任何相关信息。我可以采用手动方式,首先使用htmlwidgets::saveWidget()将html小部件保存为网站,然后使用webshot::webshot()将其转换为pdf,并使用矢量图形编辑器(如Inkscape)手动安排图形。但是,尽管手工工作,所有的转换步骤可能会导致质量下降。
也许我可以在LaTeX R-Markdown文档中用表格或列排列图形,并指定纸张尺寸以适合我的绘图。但不知怎的,这感觉不像是一个理想的解决方案,因为我可能想要在几列和几行中动态地排列我的图表,添加标题等。,这将使LaTeX/knitr中的排列非常复杂。
所以在我开始手工编织所有东西之前,我想问你是否知道一个更好的方法来安排一些html小部件图,并将它们导出到R中的pdf ?
<
最小的例子/strong>
这里有一个最小的例子来重现我的问题。假设我的目标是一个图表,比较两个不同进程的能量流彼此(Sankey图与networkD3),通过安排他们在一个网格中彼此相邻,像这样:典型的桑基情节安排
这就是我的代码:
library(networkD3)
library(grid)
library(gridExtra)
## Create simplified Data
dfSankey <- list()
dfSankey$nodes <- data.frame(Name = c("Final Energy","Conversion Losses","Useful Energy"))
#1st process
dfSankey$links1 <- data.frame(Source = c(0,0),Target=c(1,2),Value=c(30,70))
#2nd process
dfSankey$links2 <- data.frame(Source = c(0,0),Target=c(1,2),Value=c(10,60))
## Draw Sankeys
plSankey1 <- sankeyNetwork(Links = dfSankey$links1, Nodes = dfSankey$nodes, Source = 'Source',
Target = 'Target', Value = 'Value', NodeID = 'Name')
plSankey2 <- sankeyNetwork(Links = dfSankey$links2, Nodes = dfSankey$nodes, Source = 'Source',
Target = 'Target', Value = 'Value', NodeID = 'Name')
#Arrange them next to each other
grid.arrange(plSankey1,plSankey2)
这将导致开头提到的错误消息。
Windows 7, R- studio 0.99.903, R版本3.2.3,grid 3.2.3, gridExtra 2.2.1, networkD3 0.2.13
在Amit Kohli的启发下,我开始尝试flexdashboard,各种Rmarkdown格式(html, pdf, isolides,…),Rpresentations -但与我的目标相比,它们都有一些缺点。
在我看来,最好的视觉效果可以实现与闪亮应用程序。然后保存结果的网站为pdf与chrome,最后裁剪pdf与briss。
library(networkD3)
## Create simplified Data
dfSankey <- list()
dfSankey$nodes <- data.frame(Name = c("Final Energy","Conversion Losses","Useful Energy"))
#1st process
dfSankey$links1 <- data.frame(Source = c(0,0),Target=c(1,2),Value=c(30,70))
#2nd process
dfSankey$links2 <- data.frame(Source = c(0,0),Target=c(1,2),Value=c(10,60))
# Define UI for application that draws two Sankeys in columns
ui <- shinyUI(fluidPage(column(6,
h2("Process 1", align = "center"),
uiOutput("plot1.ui")
),
column(6,
h2("Process 2", align = "center"),
uiOutput("plot2.ui")
)
))
# Define server logic required to draw the sankeys
server <- shinyServer(function(input, output) {
#Render plot area relative to flow height
output$plot1.ui <- renderUI({
sankeyNetworkOutput("Plot1", height = "400px")
})
output$plot2.ui <- renderUI({
sankeyNetworkOutput("Plot2", height=paste0(400*(70/100),"px"))
})
#Render Sankeys
output$Plot1 <- renderSankeyNetwork({
sankeyNetwork(Links = dfSankey$links1, Nodes = dfSankey$nodes, Source = 'Source',
Target = 'Target', Value = 'Value', NodeID = 'Name', fontSize = 15, nodeWidth = 10)
})
output$Plot2 <- renderSankeyNetwork({
sankeyNetwork(Links = dfSankey$links2, Nodes = dfSankey$nodes, Source = 'Source',
Target = 'Target', Value = 'Value', NodeID = 'Name', fontSize = 15, nodeWidth = 10)
})
})
# Run the application
shinyApp(ui = ui, server = server)
仍然感觉有点像写一个闪亮的应用程序,并做所有这些手动转换只是为了在pdf中安排两个html小部件图形,但至少最终的pdf图片看起来非常令人愉快。