Metaviz
is tool for interactive visualization and exploration of metagenomic sequencing data. Metaviz a provides main navigation tool for exploring hierarchical feature data that is coupled with multiple data visualizations including heatmaps, stacked bar charts, and scatter plots. Metaviz supports a flexible plugin framework so users can add new d3 visualizations. You can find more information about Metaviz at http://metaviz.cbcb.umd.edu/help.
The metavizr
package implements two-way communication between the R/Bioconductor
computational genomics environment and Metaviz
. Objects in an R/Bioconductor
session can be visualized and explored using the Metaviz
navigation tool and plots. Metavizr uses Websockets to communicate between the browser Javascript client and the R/Bioconductor
session. Websockets are the protocols underlying the popular Shiny system for authoring interactive web-based reports in R.
In this vignette we will look at two data sets one from a case/control study and another with a time series. We load the first data set from the msd16s
Bioconductor package. This data is from the Moderate to Severe Diaherrial disease study in children from four countries: Banglash, Kenya, Mali, and the Gambia. Case and control stool samples were gathered from each country across several age ranges, 0-6 months, 6-12 months, 12-18 months, 18-24 months, and 24-60 months. An analysis of this data is described in Pop et al. [1].
require(metavizr)
require(metagenomeSeq)
require(msd16s)
The connection to Metaviz
is managed through a session manager object of class EpivizApp
. We can create this object and open Metaviz
using the startMetaviz
function.
app <- startMetaviz()
NOTE: The following commands are not visible when building the vignette. These commands are for registering each chart type so that the vignette will build when starting a new Metaviz session using localhost. These commands are not needed if using startMetaviz
with default which starts a Metaviz session using http://metaviz.cbcb.umd.edu.
This opens a websocket connection between the interactive R
session and the browser client. This will allow us to visualize data stored in the Metaviz
server along with data in the interactive R
session.
Windows users: In Windows platforms we need to use the service
function to let the interactive R
session connect to the epiviz
web app and serve data requests. We then escape (using ctl-c
or esc
depending on your environment) to continue with the interactive R
session. This is required anytime you want metavizr
to serve data to the web app, for example, when interacting with the UI. (We are actively developing support for non-blocking sessions in Windows platforms).
app$server$service()
For vignette purposes, we will subset the 992 msd16s
samples to those 301 from Bangladesh. Also, we will aggregate the count matrix to the species level. We have found that matrix sizes with 100 samples and 4000 features perform well for interactive visualization with an R session using WebSockets. For larger abundance matrices, we recommend using the graph database backend available at https://github.com/epiviz/metaviz-data-provider. Once having subset the data, we set the aggregation level to “class”, normalize, find features differentially abundant at the “class” level, propagate those selections to an MRexperiment that is aggreagted to “species” level, and then explore the hiearchy.
feature_order <- c("superkingdom", "phylum", "class", "order", "family", "genus", "species", "OTU")
aggregated_feature_order <- feature_order[1:7]
msd16s_species <- msd16s
fData(msd16s) <- fData(msd16s)[feature_order]
fData(msd16s_species) <- fData(msd16s_species)[aggregated_feature_order]
bangladesh <- msd16s[, which(pData(msd16s)$Country == "Bangladesh")]
bangladesh_species <- msd16s_species[, which(pData(msd16s_species)$Country == "Bangladesh")]
aggregated_species <- cumNorm(aggregateByTaxonomy(bangladesh_species, lvl="species"), p = 0.75)
aggregation_level <- "class"
aggregated_bangladesh <- aggregateByTaxonomy(bangladesh, lvl=aggregation_level)
normed_bangladesh <- cumNorm(aggregated_bangladesh, p = 0.75)
bangladesh_sample_data <- pData(normed_bangladesh)
mod <- model.matrix(~1+Dysentery, data = bangladesh_sample_data)
results_bangladesh <- fitFeatureModel(normed_bangladesh, mod)
## Warning: glm.fit: algorithm did not converge
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
logFC_bangladesh <- MRcoefs(results_bangladesh, number = nrow(normed_bangladesh))
features <- rownames(logFC_bangladesh)
featuresToKeep_names <- features[which(logFC_bangladesh[which(abs(logFC_bangladesh$logFC) > 1),]$adjPvalues < .1)]
featuresToKeep <- rep(2, length(featuresToKeep_names))
names(featuresToKeep) <- featuresToKeep_names
featuresToRemove_names <- features[!(features %in% featuresToKeep_names)]
featuresToRemove <- rep(0, length(featuresToRemove_names))
names(featuresToRemove) <- featuresToRemove_names
A metavizControl allows users to specify settings for operating over the MRexperiment object including data analysis such as normalization and log transform. We create a metavizControl with the featureSelection as the nodes that be found to be differentially abundant and those will be visible when creating Metaviz plots. The rest of the settings in the metavizControl will use the default parameters.
control <- metavizr::metavizControl(featureSelection = c(featuresToKeep, featuresToRemove))
mouseData
MRExperiment objectNow we can view the data as a heatmap calling revisualize
:
heatmap <- app$chart_mgr$revisualize(chart_type = "HeatmapPlot", chart = icicle_plot)
Using the same data, we can also revisualize it in a stacked plot to see the abundance of various features across samples. Since the measurements are added from creating the icicle_plot, we only need to add a stacked line plot.
stackedPlot <- app$chart_mgr$revisualize(chart_type ="StackedLinePlot", chart = icicle_plot)
Finally, we can update the threshold cutoff we had for fold change, pass those modifications the icicle plot, and see the updates propogate to the heat map and stacked plot. This shows the use case of statistically-guided interactive visualizations.
feature_names2 <- rownames(logFC_bangladesh[which(logFC_bangladesh[which(abs(logFC_bangladesh$logFC) > .5),]$adjPvalues < .05),])
fSelection2 <- rep(2, length(feature_names2))
names(fSelection2) <- feature_names2
app$get_ms_object(icicle_plot)$propagateHierarchyChanges(fSelection2, selectedLevels = which(feature_order==aggregation_level), request_with_labels = TRUE)
Another feature of metavizr is to visualize data using a line plot. We detail the steps to perform this analysis and create a line plot using Metaviz such as those used in Paulson et al. when analyzing this time series data with a smoothing-spline [2] and [3].
First, import the etec16s dataset, select sample data from the first 9 days, and choose the feature annotations of interest.
library(etec16s)
data(etec16s)
etec16s <- etec16s[,-which(pData(etec16s)$Day>9)]
Next, use metagenomeSeq to fit a smoothing-spline to the time series data.
featureData(etec16s)$Kingdom <- "Bacteria"
feature_order <- c("Kingdom", "Phylum", "Class", "Order", "Family", "Genus", "Species", "OTU.ID")
timeSeriesFits <- fitMultipleTimeSeries(obj=etec16s,
formula = abundance~id + time*class + AntiGiven,
class="AnyDayDiarrhea",
id="SubjectID",
time="Day",
lvl="Family",
featureOrder = feature_order,
C=0.3,
B=1,
seed=1234)
## Loading required namespace: gss
## Warning in mspreg1(s, r, id.basis, y, wt, method, alpha, varht, random, :
## gss warning in ssanova: iteration for model selection fails to converge
For plotting the data using Metaviz, we set the fit values as y-coordinates and timepoints as x-coordinates. We need to call ts2MRexperiment
with arguments for the sample and feature data, in this case timepoints and annotations, respectively.
feature_order2 <- c("Kingdom", "Phylum", "Class", "Order", "Family")
splinesMRexp <- ts2MRexperiment(timeSeriesFits, featureData = featureData(aggregateByTaxonomy(etec16s, lvl="Family", featureOrder = feature_order2)), sampleNames = timeSeriesFits[[2]]$fit$timePoints)
Finally, we add the MRexperiment as a measurement using the add_measurements
method and then visualize those measurements as a LinePlot.
splines_to_plot <- sapply(1:nrow(MRcounts(splinesMRexp)), function(i) {max(abs(MRcounts(splinesMRexp[i,]))) >= 2})
splines_to_plot_indices <- which(splines_to_plot == TRUE)
ic_plot <- app$plot(splinesMRexp[splines_to_plot_indices,], datasource_name = "etec16_base21", control=metavizControl(norm = FALSE, aggregateAtDepth = 4), feature_order = feature_order2)
## MRExperiment Object validated... PASS
## creating hierarchy_tree
## creating node_ids_table
## creating nodes_table
## creating leaf_of_table
## creating leaf_sample_count_table
splineObj <- app$data_mgr$add_measurements(splinesMRexp[splines_to_plot_indices,], datasource_name = "splines2", control = metavizControl(norm=FALSE, aggregateAtDepth = 4), feature_order = feature_order2)
## MRExperiment Object validated... PASS
## creating hierarchy_tree
## creating node_ids_table
## creating nodes_table
## creating leaf_of_table
## creating leaf_sample_count_table
splineMeasurements <- splineObj$get_measurements()
splineChart <- app$chart_mgr$visualize("LinePlot", splineMeasurements)
We can update the colors and settings on the spline chart. For example, lets limit the y axis to be between -10 and 10. To do so we use the set_chart_settings
method. We can list existing settings for a chart using the list_chart_settings
function.
## type js_class
## 1 HeatmapPlot epiviz.plugins.charts.HeatmapPlot
## 2 LinePlot epiviz.plugins.charts.LinePlot
## 3 StackedLinePlot epiviz.plugins.charts.StackedLinePlot
## 4 epiviz.ui.charts.tree.Icicle epiviz.ui.charts.tree.Icicle
## num_settings
## 1 17
## 2 16
## 3 14
## 4 5
## settings
## 1 title,marginTop,marginBottom,marginLeft,marginRight,measurementGroupsAggregator,...
## 2 title,marginTop,marginBottom,marginLeft,marginRight,measurementGroupsAggregator,...
## 3 title,marginTop,marginBottom,marginLeft,marginRight,measurementGroupsAggregator,...
## 4 title,marginTop,marginBottom,marginLeft,marginRight
## num_colors
## 1 8
## 2 20
## 3 20
## 4 10
## id label
## 1 title Title
## 2 marginTop Top margin
## 3 marginBottom Bottom margin
## 4 marginLeft Left margin
## 5 marginRight Right margin
## 6 measurementGroupsAggregator Aggregator for measurement groups
## 7 colLabel Columns labels
## 8 rowLabel Row labels
## 9 showPoints Show points
## 10 showLines Show lines
## 11 showErrorBars Show error bars
## 12 pointRadius Point radius
## 13 lineThickness Line thickness
## 14 yMin Min Y
## 15 yMax Max Y
## 16 interpolation Interpolation
## default_value
## 1
## 2 30
## 3 50
## 4 30
## 5 15
## 6 mean-stdev
## 7 colLabel
## 8 name
## 9 FALSE
## 10 TRUE
## 11 TRUE
## 12 4
## 13 3
## 14 default
## 15 default
## 16 basis
## possible_values
## 1
## 2
## 3
## 4
## 5
## 6 mean-stdev,quartiles,count,min,max,sum
## 7
## 8
## 9
## 10
## 11
## 12
## 13
## 14
## 15
## 16 linear,step-before,step-after,basis,basis-open,basis-closed,bundle,cardinal,cardinal-open,monotone
## type
## 1 string
## 2 number
## 3 number
## 4 number
## 5 number
## 6 categorical
## 7 measurementsMetadata
## 8 measurementsAnnotation
## 9 boolean
## 10 boolean
## 11 boolean
## 12 number
## 13 number
## 14 number
## 15 number
## 16 categorical
To close the connection with metaviz and the R session, we use the stop_app function.
app$stop_app()
sessionInfo()
## R version 3.4.1 (2017-06-30)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.2 LTS
##
## Matrix products: default
## BLAS: /home/biocbuild/bbs-3.5-bioc/R/lib/libRblas.so
## LAPACK: /home/biocbuild/bbs-3.5-bioc/R/lib/libRlapack.so
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=C
## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] parallel stats graphics grDevices utils datasets methods
## [8] base
##
## other attached packages:
## [1] etec16s_1.4.0 msd16s_0.110.0 metavizr_1.0.2
## [4] digest_0.6.12 data.table_1.10.4 metagenomeSeq_1.18.0
## [7] RColorBrewer_1.1-2 glmnet_2.0-10 foreach_1.4.3
## [10] Matrix_1.2-10 limma_3.32.3 Biobase_2.36.2
## [13] BiocGenerics_0.22.0 BiocStyle_2.4.0
##
## loaded via a namespace (and not attached):
## [1] nlme_3.1-131 ProtGenerics_1.8.0
## [3] bitops_1.0-6 matrixStats_0.52.2
## [5] phyloseq_1.20.0 bit64_0.9-7
## [7] httr_1.2.1 rprojroot_1.2
## [9] GenomeInfoDb_1.12.2 tools_3.4.1
## [11] backports_1.1.0 epivizr_2.6.0
## [13] vegan_2.4-3 R6_2.2.2
## [15] KernSmooth_2.23-15 mgcv_1.8-17
## [17] colorspace_1.3-2 DBI_0.7
## [19] lazyeval_0.2.0 permute_0.9-4
## [21] ade4_1.7-6 bit_1.1-12
## [23] curl_2.7 compiler_3.4.1
## [25] git2r_0.18.0 graph_1.54.0
## [27] DelayedArray_0.2.7 rtracklayer_1.36.4
## [29] scales_0.4.1 caTools_1.17.1
## [31] RBGL_1.52.0 stringr_1.2.0
## [33] Rsamtools_1.28.0 epivizrStandalone_1.4.0
## [35] rmarkdown_1.6 XVector_0.16.0
## [37] pkgconfig_2.0.1 epivizrServer_1.4.0
## [39] htmltools_0.3.6 ensembldb_2.0.3
## [41] rlang_0.1.1 RSQLite_2.0
## [43] BiocInstaller_1.26.0 shiny_1.0.3
## [45] jsonlite_1.5 BiocParallel_1.10.1
## [47] gtools_3.5.0 RCurl_1.95-4.8
## [49] magrittr_1.5 GenomeInfoDbData_0.99.0
## [51] biomformat_1.4.0 munsell_0.4.3
## [53] Rcpp_0.12.12 S4Vectors_0.14.3
## [55] ape_4.1 stringi_1.1.5
## [57] yaml_2.1.14 MASS_7.3-47
## [59] SummarizedExperiment_1.6.3 zlibbioc_1.22.0
## [61] rhdf5_2.20.0 gplots_3.0.1
## [63] plyr_1.8.4 AnnotationHub_2.8.2
## [65] grid_3.4.1 blob_1.1.0
## [67] gdata_2.18.0 lattice_0.20-35
## [69] splines_3.4.1 Biostrings_2.44.1
## [71] multtest_2.32.0 GenomicFeatures_1.28.4
## [73] knitr_1.16 igraph_1.1.1
## [75] GenomicRanges_1.28.4 rjson_0.2.15
## [77] reshape2_1.4.2 codetools_0.2-15
## [79] biomaRt_2.32.1 stats4_3.4.1
## [81] XML_3.98-1.9 evaluate_0.10.1
## [83] httpuv_1.3.5 gtable_0.2.0
## [85] ggplot2_2.2.1 mime_0.5
## [87] xtable_1.8-2 AnnotationFilter_1.0.0
## [89] survival_2.41-3 tibble_1.3.3
## [91] OrganismDbi_1.18.0 iterators_1.0.8
## [93] epivizrData_1.4.0 GenomicAlignments_1.12.1
## [95] AnnotationDbi_1.38.1 memoise_1.1.0
## [97] IRanges_2.10.2 cluster_2.0.6
## [99] interactiveDisplayBase_1.14.0 gss_2.1-7
References:
[1] Pop, M., Walker, A.W., Paulson, J., Lindsay, B., Antonio, M., Hossain, M.A., Oundo, J., Tamboura, B., Mai, V., Astrovskaya, I. and Bravo, H.C., 2014. Diarrhea in young children from low-income countries leads to large-scale alterations in intestinal microbiota composition. Genome biology, 15(6), p.1.
[2] Pop, M., Paulson, J.N., Chakraborty, S., Astrovskaya, I., Lindsay, B.R., Li, S., Bravo, H.C., Harro, C., Parkhill, J., Walker, A.W. and Walker, R.I., 2016. Individual-specific changes in the human gut microbiota after challenge with enterotoxigenic Escherichia coli and subsequent ciprofloxacin treatment. BMC genomics, 17(1), p.1.
[3] Paulson J.N., Talukder H., and Bravo H.C, Longitudinal differential abundance analysis of microbial marker-gene surveys using smoothing splines. In Submission.