Skip to contents

shinyngs is two things at once: a set of Shiny modules that assemble into an interactive application, and a library of standalone plotting functions that back those modules. The plotting functions are exported and return plain ggplot/plotly objects, so you can call them directly from an R script, an R Markdown or Quarto report, or a Shiny app of your own, without building a full shinyngs application. This is exactly how downstream pipelines (for example nf-core/differentialabundance) embed shinyngs plots in their reports.

The standalone plotting API

Each of these takes data in and returns a plot object out. None of them needs a running Shiny session.

Function Returns Shows
interactive_scatterplot(), static_scatterplot() plotly / ggplot Generic 2D/3D scatter (the engine behind PCA, MA, volcano, fold-change)
interactive_screeplot() plotly Variance explained per principal component
interactive_pca_metadata_heatmap() plotly ANOVA associations between PCs and sample metadata
interactive_heatmap() plotly Clustered, annotated expression heatmap
interactive_clustering_dendrogram(), clustering_dendrogram() plotly / ggplot Sample clustering dendrogram
static_boxplot(), interactive_boxplot(), interactive_quartiles() ggplot / plotly Per-sample abundance distributions
static_densityplot(), interactive_densityplot() ggplot / plotly Abundance density curves
interactive_topgene_boxplots(), static_topgene_boxplots() plotly / ggplot Faceted boxplots of top differential features
interactive_cluster_profiles() plotly Feature-wise cluster expression profiles
interactive_upset() plotly Intersections of feature sets across contrasts
interactive_barcodeplot() plotly Gene-set enrichment barcode over a ranking
interactive_barchart(), interactive_count_barplot() plotly Bar charts and categorical counts
interactive_illumina_control_probes() plotly Illumina array control-probe QC
make_color_scale() character vector A colour-blind-safe categorical palette to colour any of the above

See the module and panel catalogue for which app panel each of these backs.

Calling a plot from a report

A minimal example: colour a PCA scatter by a metadata variable, using compile_pca_data() for the coordinates and make_color_scale() for a consistent palette.

library(shinyngs)

pca <- compile_pca_data(my_matrix)
groups <- my_metadata$treatment

interactive_scatterplot(
  x = pca$coords[, "PC1"],
  y = pca$coords[, "PC2"],
  colorby = groups,
  palette = make_color_scale(nlevels(factor(groups))),
  xlab = "PC1",
  ylab = "PC2"
)

The heatmap functions follow the same shape: pass a matrix (and, optionally, a sample_annotation data frame) and get a widget back.

interactive_heatmap(
  plotmatrix = my_matrix[select_variable_genes(my_matrix, ntop = 500), ],
  sample_annotation = my_metadata["treatment"]
)

Compute versus render: what shinyngs does and does not do

shinyngs is a viewer, not an analysis engine. It renders results you have already computed. A handful of exported helpers do lightweight preparation that the plots need, and it is fine to use them, but they are not a statistics package:

Differential statistics, enrichment testing and similar analysis belong upstream (in your pipeline); pass their outputs in and let shinyngs display them.

Publication-quality output

Every interactive plot rendered inside the app carries a download button that honours an app-wide PNG/SVG toggle, so any plot can be exported as vector SVG for print. When you call the plotly functions yourself, apply the same configuration to get a named SVG download button:

p <- interactive_scatterplot(x, y, colorby = groups)
plotly::config(
  p,
  toImageButtonOptions = list(format = "svg", filename = "pca")
)

Gotcha: self-contained HTML reports

If you embed these plotly widgets in a self-contained HTML report (Quarto embed-resources: true, or rmarkdown self_contained: yes), the widget’s JavaScript dependencies must be inlined into the single output file. When widgets are emitted from a loop with results = 'asis', htmlwidgets only registers the dependencies it has seen rendered normally. If a later widget pulls in a dependency that no earlier “primed” widget did, that dependency is missing at runtime and the widget fails to draw.

The fix is to “prime” the report once, near the top, by rendering a throwaway instance of each widget type (and each optional feature) you will emit later, so its dependencies are collected into the self-contained file. This is a property of htmlwidgets and self-contained HTML in general, not specific to shinyngs, but it is the most common surprise when moving these plots into a static report.

Embedding the Shiny modules in your own app

The modules follow a three-function convention: a *Input() UI function, a *Output() UI function, and a server function of the same base name driven by shiny::moduleServer(). Add the UI pair to your layout and call the server function inside your server, passing the ExploratorySummarizedExperimentList the module should read from. The developer guide walks through this and through adding a new module.

A note on in-widget controls

interactive_scatterplot()’s opt-in colorby_menu argument adds a dropdown inside the widget for switching the colouring variable. That control is meant for standalone/report contexts where there is no surrounding Shiny UI. Inside a shinyngs app the colouring variable is chosen with a Shiny selectInput, so the modules deliberately leave colorby_menu off to avoid two competing colour controls on screen. If you build your own app around these functions, pick one mechanism or the other, not both.