Setup
Load the package:
Snapshot configuration (optional)
The charts can be embedded in static documents (PDF, Word, etc.). See also auto-snapshots below. Here we run a small helper function for making sure that snapshots are PNG images with a resolution of 300 DPI. This is only relevant if “knitting” this document to PDF or Word, etc. Otherwise, this has no effect.
Note This modifies the
dev,dpiandscreenshot.optssettings for all chunks. However, it is always possible to change the settings for individual chunks.
Data formats
Long format without abundances
The example dataset used in this tutorial contains 54 records of macrofungi identified during two surveys on a grassland plot in Switzerland.
The grasslandfungi.records version of the dataset simply
consists of taxonomic lineages, one row per record (taxa can be
repeated):
data(grasslandfungi.records)
head(grasslandfungi.records[c(3:5, 7)])
#> class order family species
#> 1 Agaricomycetes Agaricales Hygrophoraceae Gliophorus psittacinus
#> 2 Agaricomycetes Russulales Russulaceae Lactarius deterrimus
#> 3 Agaricomycetes Agaricales Inocybaceae Inocybe oreina
#> 4 Agaricomycetes Agaricales Cortinariaceae Cortinarius infractus
#> 5 Agaricomycetes Agaricales Entolomataceae <NA>
#> 6 Agaricomycetes Russulales Russulaceae Russula sanguineaThe taxonomic hierarchy of the records from the two visits can easily be displayed, whereby the widths are proportional to taxa abundances:
plot_krona(grasslandfungi.records)Hierarchy + abundances
Another version of the dataset (grasslandfungi) has
aggregated taxonomic lineages along with taxa abundances for both
visits, as well as the total record count:
data(grasslandfungi)
head(grasslandfungi[c('family', 'species', 'visit_1', 'visit_2', 'n_total')])
#> family species visit_1 visit_2 n_total
#> Cnrc Bolbitiaceae Conocybe rickenii 0 2 2
#> Pncm Bolbitiaceae Panaeolus acuminatus 0 2 2
#> Pnpp Bolbitiaceae Panaeolus papilionaceus 1 0 1
#> Clvr Clavariaceae Clavaria fumosa 1 0 1
#> Crnf Cortinariaceae Cortinarius infractus 1 0 1
#> Crsp Cortinariaceae Cortinarius spilomeus 0 2 2If the taxa are simply provided without abundances, every one of them obtains the same weight in the chart as well (=visualization of presences/detections):
tax_ranks <- names(grasslandfungi.records)
plot_krona(grasslandfungi[tax_ranks])To scale by abundance, we supply n_total as second
argument:
plot_krona(grasslandfungi[tax_ranks], grasslandfungi$n_total)The second
magnitudeargument can also be a matrix/data frame with abundances from different surveys (samples, datasets), which can optionally be displayed separately (see datasets, more details in themake_krona()documentation). By default, taxa widths are scaled by the row totals. Consequently, supplyinggrasslandfungi[c('visit_1', 'visit_2')]asmagnitudegives the same result as supplyinggrasslandfungi$n_total.
Phyloseq objects
The popular phyloseq
format is supported out of the box, see
vignette("phyloseq").
Hierarchical list data structure
Alternatively, the classification can be a hierarchical data structure composed of nested lists:
classification <- list(
name = 'Root',
n = 15,
list(
name = 'A',
n = 10,
list(name = 'A.1', n = 5),
list(name = 'A.2', n = 3)
),
list(name = 'B', n = 5)
)
plot_krona(classification)The node attribute
nameis mandatory. Thenattribute indicates the magnitude and can be omitted or named differently (magnitude = 'othername')
Pre-generated HTML charts
Finally, it is possible to directly display file containing a Krona chart:
plot_krona(file = 'http://marbl.github.io/Krona/examples/metarep-blast.krona.html')… or plot_krona() can display HTML code stored in a
character string. In this example, the HTML is generated by
make_krona():
chart_html <- make_krona(classification)
plot_krona(chart_html)Chart generation options
So far, plot_krona() has been used to directly display
the Krona charts as HTML widget.
Behind the scenes, make_krona() acts as the “working horse”
for generating the chart code. This function can be used in the same way
as plot_krona(), but returns the HTML as character string
instead of a HTML widget. Both functions can also save the chart to a
HTML file with outfile:
# save HTML in character string
chart_html <- make_krona(classification)
# display AND save the chart
plot_krona(chart_html, outfile = 'chart.html')
# save the chart
make_krona(classification, outfile = 'chart.html')The two functions offer almost all features of the original Krona software, as described in the following. The generated charts are identical or almost identical as the ones generated by Krona.
Datasets
Multiple datasets can grouped within the same chart, selectable from a list in the top-left corner.
In this example the two separate surveys from the grassland fungi
dataset are visualized separately (visit_1 and
visit_2). To prevent the aggregation of the counts across
the visit_1 and visit_2 magnitude columns, we
have to specify dataset_group = 'separate':
plot_krona(grasslandfungi[tax_ranks],
grasslandfungi[c('visit_1', 'visit_2')],
dataset_group = 'separate')dataset_group can also be a character vector of length
ncol(magnitude); for phyloseq objects
group_vars can be specified (see
vignette(“phyloseq”)`).
In static contexts without user interaction (PDF, Word, etc.), a snapshot of the first dataset (visit_1) is taken.
Attributes: Displaying extra information
Additional taxon-specific information can be displayed in the
top-right corner when clicking on a node of the
hierarchy. This extra-information is configured through
ChartAttribute().
For example, the grassland fungi dataset has three more columns with useful information: the current IUCN redlist status in Switzerland, and taxon IDs in the GBIF and SwissFungi databases:
head(grasslandfungi[c('species', 'redlist_CH', 'gbif_taxon_id', 'swissfungi_taxon_id')])
#> species redlist_CH gbif_taxon_id swissfungi_taxon_id
#> Cnrc Conocybe rickenii LC 2529824 1219
#> Pncm Panaeolus acuminatus VU 2526744 5195
#> Pnpp Panaeolus papilionaceus LC 3317061 5207
#> Clvr Clavaria fumosa EN 5244508 952
#> Crnf Cortinarius infractus LC 8168239 1640
#> Crsp Cortinarius spilomeus LC 9174514 1852We can now add all the redlist status and GBIF + SwissFungi links to the chart (explore by clicking on taxa and observing the top-right corner):
attrs <- list(
ChartAttribute('Redlist status', data = grasslandfungi$redlist_CH),
ChartAttribute(
'GBIF',
data = as.character(grasslandfungi$gbif_taxon_id),
hrefBase = 'https://www.gbif.org/species/'
),
ChartAttribute(
'SwissFungi',
data = as.character(grasslandfungi$swissfungi_taxon_id),
# to display text instead of the ID (be aware that this makes HTML files larger)
# text = 'SwissFungi',
hrefBase = 'https://www.wsl.ch/map_fungi/search?taxon='
)
)
plot_krona(grasslandfungi[tax_ranks], grasslandfungi$n_total, attributes=attrs,
total_label = 'Records')Click on species nodes and check the GBIF/SwissFungi links in the topright corner
Note on higher taxonomic ranks: If numeric IDs were provided, they would be averaged at higher ranks, which produces incorrect IDs for the genus, family, etc. ranks. Therefore, we specified
as.character(taxon_id); as text data is only shown if all child nodes are consistent. Alternatively, specifyonly_ranks = 'species'. See also summary_fn inChartAttribute().
Even adding extra information for only one or a few nodes in the
hierarchy is possible, assuming that both the classification
and the magnitudes data have row names to identify
them. Here we link the global redlist page for Ramaria broomei
= Phaeoclavulina macrospora (zoom into Gomphaceae and click on
the species to see the link):
attrs <- list(
#...
ChartAttribute(
'Global redlist',
data = c(Phmc = '111880'),
text = 'VU C2a(i)',
hrefBase = 'https://redlist.info/iucn/species_view/'
)
)
plot_krona(grasslandfungi[tax_ranks],
grasslandfungi[,'n_total', drop = FALSE],
attributes = attrs)Attributes in hierarchical list classification
In a hierarchical list data structure, attribute information is easily added:
classification <- list(
name = 'Root',
n = 15,
list(
name = 'A',
n = 10,
info = 'Info about A'
)
#(...)
)
plot_krona(classification, attributes = list(
ChartAttribute('info', displayName = 'Information') # displayName is optional
))Advanced HTML chart options
Behind the scenes, make_krona() assembles an XML
document, which is then passed to
generate_krona_html().
Use KronaTools instead
To use the official Krona
toolset instead of the internal method, specify
make_krona(..., method = 'kronatools') (see
kt_import_xml()). The result should usually be the
same.
Remote resources instead of self-contained HTML
By default, Krona charts are self-contained HTML files that can be
displayed without internet connection. Images and the JavaScript code
are embedded in every file. If generating many files, an external
resources directory can be specified (see KronaOpts()):
plot_krona(grasslandfungi.records, resources_url = 'https://marbl.github.io/Krona/')Use
set_krona_opts()to set this option for all following charts.
To copy the assets delivered with this R package (= latest Krona code
and some images, d1479b3)
to a target directory, call:
copy_krona_resources('resources')Optimize HTML file size
A little space can be saved by including a “minified” version of the JavaScript code:
plot_krona(classification, minify = TRUE)
set_krona_opts(minify = TRUE)Styling embedded charts
The appearance of Krona charts can be changed with buttons and
checkboxes, etc., and default values can be configured for every of
these. If displaying the chart in a browser, the initial appearance can
be configured with URL parameters added to the URL
(...?key1=value1&key2=value2), e.g. http://marbl.github.io/Krona/examples/phymmbl.krona.html?depth=3&font=15.
For charts embedded in R-Markdown,
display = ChartDisplayOpts(...) can be specified:
plot_krona(grasslandfungi.records,
display = ChartDisplayOpts(font = 15, showMagnitude = TRUE, key = FALSE))In R-Markdown chunks, set
cache = FALSEif adjusting display options has no effect.
To make all following charts look the same, use:
set_chart_display_opts(font = 15, showMagnitude = TRUE, key = FALSE)Auto-snapshots
In “static” documents such as PDF, Word, etc., snapshots are
automatically taken. In this “snapshot mode”, no buttons and other
controls are shown. This behavior can be forced (or prevented) with
interactive = TRUE or interactive = FALSE:
plot_krona(grasslandfungi.records, interactive = FALSE)It is also possible to force a snapshot in interactive contexts by
setting the R-Markdown chunk option screenshot.force = TRUE
and calling plot_krona() with
interactive = FALSE. To do this globally for all
chunks:
set_chart_opts(interactive = FALSE)
knitr::opts_chunk$set(screenshot.force = TRUE)To create a snapshot image (not HTML file) manually:
make_krona(grasslandfungi.records,
outfile = 'chart.html',
snapshot = TRUE)
webshot2::webshot('chart.html', 'chart-snapshot.png', 672, 480)
# file.remove('chart.html')Details on snapshot formats
On top of this tutorial, the snapshot format was set to PNG. In PDF documents, the default would be to embed the charts as vector graphics and text. But generating PNG images instead can be useful due to different reasons:
- file sizes can be smaller for complex charts
- thin lines may look nicer
- the resolution might not be correct (see issue)
But you can still try without these settings (leave
dev = NULL) to see how it looks like. Also, the PNG
dimensions might not be correct (see also below).
Plot dimensions
The charts may be sized differently depending on the context:
Inline view in R-Markdown chunks (RStudio): Always the same size
HTML documents: Charts are sized with
fig.width and fig.height chunk options (in
inches)
PDF/Word documents: HTML widget snapshots seem to
always be scaled to the full width in the output, but
still the image resolution and font size are determined by
fig.width/fig.height and dpi
settings. Figure dimensions around 6-7 inches should look as expected
(consider setting this at the top of the document:
knitr::opts_chunk$set(fig.width=6, fig.height=6)). To make
plots smaller, it is possible to modify out.width
(e.g. knitr::opts_chunk$set(out.width = '50%')). However,
the resolution (dpi) and font size
(ChartDisplayOpts(font = 15)) may need to be adjusted.
Shiny apps
This example code shows how to use these charts in a Shiny app (opens in a separate window). It also requires phyloseq to be installed.
library(shiny)
library(phyloseq)
library(taxplore)
data(grasslandfungi, grasslandfungi.records, GlobalPatterns, enterotype)
# each dataset is a list(taxonomy, magnitude)
tax_ranks <- names(grasslandfungi.records)
datasets <- list(
`Survey of grassland fungi` = list(grasslandfungi[tax_ranks], grasslandfungi$n_total),
`Global patterns of 16S diversity` = list(tax_table(GlobalPatterns), taxa_sums(GlobalPatterns)),
`Enterotypes of the human gut microbiome` = list(tax_table(enterotype), taxa_sums(enterotype))
)
ui <- bslib::page_fluid(
titlePanel('Visualize community datasets'),
radioButtons(
'dataset',
'Select dataset',
choices = names(datasets),
selected = names(datasets)[1]
),
checkboxInput('use_abund', 'Use abundances', value = TRUE),
KronaChartOutput('chart', height='40em')
)
server <- function(input, output) {
output$chart <- renderKronaChart({
d <- datasets[[input$dataset]]
plot_krona(d[[1]], magnitude = if (input$use_abund) d[[2]])
})
}
shinyApp(ui = ui, server = server)