「写在前面」
学习一个软件最好的方法就是啃它的官方文档。本着自己学习、分享他人的态度,分享官方文档的中文教程。软件可能随时更新,建议配合官方文档一起阅读。推荐先按顺序阅读往期内容:
1.quarto 教程 1:Hello, Quarto
2.quarto 教程 2:Computations
3.quarto 教程 3:Authoring
4.Quarto Dashboards 教程 1:Overview
5.Quarto Dashboards 教程 2:Dashboard Layout
官网教程:
https://quarto.org/docs/dashboards/data-display.html
仪表盘是用于提供导航和呈现数据的组件组合。下面本文将介绍如何使用图、表格、数值框来呈现数据,以及如何在仪表盘中包含叙述性内容。
图是迄今为止仪表板中显示的最常见的内容类型。支持基于 JavaScript 的交互式绘图(例如 Altair 和 Plotly)和基于标准光栅的绘图(例如 Matplotlib 或 ggplot2)。
下面本文提供了一些在仪表盘中包含绘图的特定于语言的提示和技术,本教程只展示了 R 语言,Python 语言见官方文档。
htmlwidgets 框架为 JavaScript 数据可视化库提供高级 R 绑定。一些流行的 htmlwidgets 包括 Plotly、Leaflet、dygraphs。
您可以像使用普通 R plots 一样使用 htmlwidgets。例如,以下是我们嵌入 Leaflet 地图的方法:
library(leaflet)
leaflet() %>%
addTiles() %>%
addMarkers(lng=174.768, lat=-36.852,
popup="The birthplace of R")
CRAN 上有几十个提供 htmlwidgets 的包。您可以在 htmlwidgets showcase 中找到几个更流行的 htmlwidgets 的示例用法,并浏览 gallery 中的所有可用 widgets。
您可以在仪表盘中使用标准 R 栅格图形(base、lattice、grid,等)创建的任何图。将标准 R 图形与静态仪表盘一起使用时,您需要更加注意使绘图的大小适合页面布局。请注意,这对于交互式 Shiny 仪表盘中的绘图来说不是问题,因为所有绘图类型均由 Shiny 动态调整大小。
静态仪表盘中良好的尺寸调整行为的关键是定义 knitr fig-width
和 fig-height
选项,使绘图能够尽可能紧密地适合其布局容器。
下面是一个布局示例,其中包含来自 R 基础图形的 3 个图:
## Row {height="65%"}
```{r}
#| fig-width: 10
#| fig-height: 8
plot(cars)
```
## Row {height="35%"}
```{r}
#| fig-width: 5
#| fig-height: 4
plot(pressure)
```
```{r}
#| fig-width: 5
#| fig-height: 4
plot(airmiles)
```
我们为每个图指定了明确的fig-height
和fig-width
,以便它们的渲染大小尽可能接近其布局容器。请注意,这些尺寸的理想值通常需要通过实验来确定。
Tip
对于静态仪表盘,使用基于 JavaScript 的绘图有利有弊。虽然基于 JavaScript 的绘图可以比静态绘图更好地处理调整大小以填充其容器,但它们还将基础数据直接嵌入到已发布的页面中(每个绘图一份数据集的副本),这可能会导致加载时间变慢。对于交互式 Shiny 仪表盘,所有绘图类型的大小都是动态调整的,因此调整大小行为不像静态仪表盘那样需要担心。
您可以通过以下两种方式之一将数据表包含在仪表盘中:
下面我们提供了一些在仪表盘中包含表格的特定于语言的提示和技术。
有许多 R 包可用于生成表格输出。本文将在下面介绍两种更流行的方法(kable 和 DT)。
简单的 markdown 表非常适合少量记录(即 20-250 行)。使用knitr::kable()
函数输出 markdown 表:
```{r}
knitr::kable(mtcars)
```
仪表盘中的简单 markdown 表格会自动填充其容器(根据需要水平和垂直滚动)。
DT 包(DataTables JavaScript 库的接口)可以将 R 矩阵或数据框显示为支持过滤、分页和排序的交互式 HTML 表。
要包含 DataTable,请使用DT::datatable
函数:
```{r}
library(DT)
datatable(mtcars)
```
Options
请注意,仪表盘内会自动设置一些DT
选项,以确保它们在不同尺寸的卡片中良好显示。选项默认值为:
options(DT.options = list(
bPaginate = FALSE,
dom = "ifrt",
language = list(info = "Showing _TOTAL_ entries")
))
您可以根据需要指定替代选项来覆盖这些默认值。
数值框是在仪表盘中突出显示简单值的好方法。例如,这是一个包含三个数值框的仪表盘行:
以下是您可以用来创建这些数值框的代码。请注意,我们在本示例中混合使用了 Python 和 R 单元来说明每种语言的语法。另请注意,我们假设变量 articles
、comments
和 spam
是先前在文档中计算的。
## Row
```{python}
#| content: valuebox
#| title: "Articles per day"
#| icon: pencil
#| color: primary
dict(
value = articles
)
```
```{python}
#| content: valuebox
#| title: "Comments per day"
dict(
icon = "chat",
color = "primary",
value = comments
)
```
```{r}
#| content: valuebox
#| title: "Spam per day"
list(
icon = "trash",
color = "danger",
value = spam
)
```
您可以选择在 YAML 中或在单元格打印的 dict()
或 list()
(分别适用于 Python 和 R)中指定数值框选项。当您希望图标或颜色根据值动态变化时,后一种语法很方便。
数值框中使用的icon
可以是 2,000 个可用的bootstrap icons中的任何一个。
color
可以是任何 CSS 颜色值,但是有一些专为仪表盘调整的颜色别名,您可能会考虑默认使用:
Color Alias | Default Theme Color(s) |
---|---|
primary | Blue |
secondary | Gray |
success | Green |
info | Bright Blue |
warning | Yellow/Orange |
danger | Red |
light | Light Gray |
dark | Black |
虽然别名适用于所有themes,但它们对应的颜色有所不同。
在 Shiny 交互式仪表盘中,您可以拥有根据应用程序状态动态更新的数值框。有关如何执行此操作的详细信息是特定于语言的:
使用 bslib::value_box()
函数以及从 bsicons
包中绘制的可选图标。例如:
```{r}
library(bslib)
library(bsicons)
value_box(
title = "Value",
value = textOutput("valuetext"),
showcase = bs_icon("music-note-beamed")
)
```
您还可以使用纯 Markdown 创建数值框,在这种情况下,您通常会通过内联表达式包含该值。例如:
## Row
::: {.valuebox icon="pencil" color="blue"}
Articles per day
`{python} articles`
:::
虽然您经常使用绘图和表格填充仪表盘卡片,但您也可以在仪表盘中的任何位置包含任意的 markdown 内容。
下面是一个仪表盘,其中一列的最后一张卡片是纯 markdown:
要做到这一点,只需在其他单元格旁边包含一个.card
div:
## Column
```{python}
#| title: Population
px.area(df, x="year", y="pop", color="continent",
line_group="country")
```
```{python}
#| title: Life Expectancy
px.line(df, x="year", y="lifeExp", color="continent",
line_group="country")
```
::: {.card}
Gapminder combines data from multiple sources into
unique coherent time-series that can’t be found
elsewhere. Learn more about the Gampminder dataset at
.
:::
请注意,如果您使用的是 Jupyter Notebook 进行创作,则 markdown 单元格将自动变为.Card
div(即它们不需要显式的:::
div 封套)。
要在单元格输出的同时包含内容,只需将单元格和内容都包含在.card
div 中即可。例如:
::: {.card title="Life Expectancy"}
```{python}
px.line(df, x="year", y="lifeExp", color="continent",
line_group="country")
```
Gapminder combines data from multiple sources into
unique coherent time-series that can’t be found
elsewhere. Learn more about the Gampminder dataset at
.
:::
包含在仪表盘最顶部的内容(而不是明确包含在 .content
div 中)被视为主导内容,并且将按原样包含,不带卡片样式(例如,无边框)。例如:
---
title: "My Dashboard"
format: dashboard
---
This content will appear above all of the other
rows/columns, with no border.
## Row
```{r}
print("")
```
您可以使用内联表达式使文本内容动态化。例如,这里有一行包含使用 Python 表达式的文本内容:
::: {.card}
The sample size was `{python} sample`. The mean reported
rating was `{python} rating`.
:::
notebook 或源文档中每个计算单元的输出将包含在卡片中。下面我们描述了创建卡片时要遵守的一些特殊规则。
您可以通过打印title=
表达式作为单元格的第一个输出来创建动态title
(与将title=
包含为 YAML 单元格选项相反)。例如:
```{r}
library(leaflet)
lat <- 48
long <- 350
cat("title=", "World Map at", lat, long)
leaflet() |> addTiles() |>
setView(long, lat, zoom = 2)
```
不产生输出的单元不会成为卡片(例如,用于导入包、加载和过滤数据等的单元)。如果某个单元产生了您想要排除的意外输出,请向该单元格添加output: false
选项:
```{python}
#| output: false
# (code that produces unexpected output)
```
默认情况下,顶级表达式的所有输出都显示在仪表盘中。这意味着可以轻松地从一个单元格生成多个图。例如:
```{python}
#| title: "Tipping Behavior"
px.box(df, x="sex", y="total_bill", color="smoker")
px.violin(df, x="sex", y="total_bill", color="smoker")
```
此行为对应于 Jupyter shell interactivity 的"all"
设置。您可以使用ipynb-shell-interactivity
选项在 Quarto 中自定义此行为。
如果一个单元格产生多个输出,您可以使用单元格布局选项来组织它们的显示。例如,这里我们修改示例以使用layout-ncol
选项并排显示绘图:
```{python}
#| title: "Tipping Behavior"
#| layout-ncol: 2
px.box(df, x="sex", y="total_bill", color="smoker")
px.violin(df, x="sex", y="total_bill", color="smoker")
```
有关自定义布局的其他文档,请参阅有关Figures的文章。
注:本文为个人学习笔记,仅供大家参考学习,不得用于任何商业目的。如有侵权,请联系作者删除。
本文由 mdnice 多平台发布