在基于 HTML 模板的 Shiny App 中使用 Plotly 失败
Posted
技术标签:
【中文标题】在基于 HTML 模板的 Shiny App 中使用 Plotly 失败【英文标题】:Using Plotly in Shiny App based on a HTML template fails 【发布时间】:2018-08-03 15:10:05 【问题描述】:我正在构建一个基于 html 模板的 Shiny 应用程序,我想将 plotly 用于图表。我正在努力将图表插入模板。
以下代码可以正常工作:
library(shiny)
library(plotly)
shinyApp(
ui <- fluidPage(plotlyOutput("plot1")),
server <- function(input, output)
p <- plot_ly(mtcars, x = ~mpg, y = ~wt, type = 'scatter', mode = 'markers')
output$plot1 <- renderPlotly(p)
)
但是,当我将应用程序更改为使用模板时,我既不能使用 renderPlotly
也不能使用 renderUI
。
<!doctype html>
<html lang="en">
<head>
<script src="shared/jquery.js" type="text/javascript"></script>
<script src="shared/shiny.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="shared/shiny.css"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="w3.css">
</head>
<body>
<h1>HTML Template UI</h1>
<div id="plot1" class="shiny-plot-output" style="width: 100%; height: 300px; border: 1px solid red"></div>
<div id="plot2" class="shiny-html-output" style="width: 100%; height: 300px; border: 1px solid blue"></div>
</body>
</html>
app.R
library(shiny)
library(plotly)
shinyApp(
ui <- htmlTemplate("template.html"),
server <- function(input, output)
p <- plot_ly(mtcars, x = ~mpg, y = ~wt)
output$plot1 <- renderPlotly(p)
output$plot2 <- renderUI(HTML(paste(htmltools::tagList(list(p)))))
)
有什么方法可以在基于 HTML 模板的 Shiny 应用中使用 plotly 吗?
【问题讨论】:
看看这个:shiny.rstudio.com/articles/html-ui.html @MLavoie 谢谢,我已经从那个例子开始了,但问题是他们在那里没有使用情节。 【参考方案1】:有一种更优雅、更简单的方法可以实现这一点。在这个 RStudio article 中有很好的描述。
要包含必要的 HTML 和 JS 依赖项,您可以在 htmlTemplate 的标题中包含 headContent()
。如果您需要 Bootstrap 组件(actionButtons、tabsetPanel),您还必须在标题中包含bootstrapLib()
。确保这些命令位于双大括号内,例如 bootstrapLib()
。
您还可以将生成输入和输出的代码(如 plotly)放在这样的大括号中,这将自动创建 html 组件并为您包含 JavaScript 依赖项。
这使得 template.html 更加简洁。
template.html
<!doctype html>
<html lang="en">
<head>
headContent()
</head>
<body>
<h1>HTML Template UI</h1>
<div class="container-fluid">
plotlyOutput("plot1")
uiOutput("plot2")
</div>
</body>
</html>
app.R
library(shiny)
library(plotly)
p <- plot_ly(mtcars, x = ~mpg, y = ~wt, type = 'scatter', mode = 'markers')
ui <- htmlTemplate("template.html")
server <- function(input, output)
output$plot1 <- renderPlotly(p)
output$plot2 <- renderUI(HTML(paste(htmltools::tagList(list(p)))))
【讨论】:
谢谢 SeGa,这听起来是一个很好的提示,尤其是我现在的模板中有超过 2000 行。【参考方案2】:尝试使用此模板:
<!doctype html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="application/shiny-singletons"></script>
<script type="application/html-dependencies">json2[2014.02.04];jquery[1.12.4];shiny[1.0.5];htmlwidgets[1.0];plotly-binding[4.7.1.9000];bootstrap[3.3.7]</script>
<script src="shared/json2-min.js"></script>
<script src="shared/jquery.min.js"></script>
<link href="shared/shiny.css" rel="stylesheet" />
<script src="shared/shiny.min.js"></script>
<script src="htmlwidgets-1.0/htmlwidgets.js"></script>
<script src="plotly-binding-4.7.1.9000/plotly.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="shared/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<script src="shared/bootstrap/js/bootstrap.min.js"></script>
<script src="shared/bootstrap/shim/html5shiv.min.js"></script>
<script src="shared/bootstrap/shim/respond.min.js"></script>
</head>
<body>
<h1>HTML Template UI</h1>
<div class="container-fluid">
<div id="plot1" class="plotly html-widget html-widget-output" style="width: 100%; height: 300px; border: 1px solid red"></div>
<div id="plot2" class="shiny-html-output" style="width: 100%; height: 300px; border: 1px solid blue"></div>
</div>
</body>
</html>
【讨论】:
感谢您的回答。我还没有来自您的标头(html 小部件等)的这些依赖项,所以它在我这边还没有工作,但它看起来很有希望。我现在正在安装它 :-) 虽然很高兴知道还有一种更“本机”的方式将 plotly 嵌入模板中,即在一些具有 class="shiny-x-output" 的对象中。 @mattino 请您运行上面的第一个 R 代码,单击浏览器中的右键,选择“可视化源代码”(或类似的东西)并发布结果吗?谢谢。 带有 plot1 和 plot2 div 的整个 html 正文:imgur.com/a/qksgz 终于在我的机器上生成了。正如您所暗示的,这是 HTML 模板中缺少链接的问题。解决方案是首先使用fluidPage() 生成一个页面,然后将其标题复制到模板:-)以上是关于在基于 HTML 模板的 Shiny App 中使用 Plotly 失败的主要内容,如果未能解决你的问题,请参考以下文章