Skip to content

Commit be032f4

Browse files
authored
Merge pull request #46 from microbiome/prevalence
Prevalence
2 parents da0700c + 6817ecd commit be032f4

15 files changed

+405
-54
lines changed

DESCRIPTION

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: iSEEtree
2-
Version: 1.1.3
2+
Version: 1.1.4
33
Authors@R:
44
c(person(given = "Giulio", family = "Benedetti", role = c("aut", "cre"),
55
email = "giulio.benedetti@utu.fi",
@@ -12,12 +12,10 @@ Authors@R:
1212
comment = c(ORCID = "0000-0001-5537-637X")))
1313
Title: Interactive visualisation for microbiome data
1414
Description:
15-
iSEEtree is an extension of iSEE for the TreeSummarizedExperiment.
16-
It leverages the functionality from the miaViz package for microbiome data
17-
visualisation to create panels that are specific for
18-
TreeSummarizedExperiment objects. Not surprisingly, it also depends on the
19-
generic panels from iSEE.
20-
biocViews: Microbiome, Software, Visualization, GUI, ShinyApps, DataImport
15+
iSEEtree is an extension of iSEE for the TreeSummarizedExperiment data
16+
container. It provides interactive panel designs to explore hierarchical
17+
datasets, such as the microbiome and cell lines.
18+
biocViews: Software, Visualization, Microbiome, GUI, ShinyApps, DataImport
2119
License: Artistic-2.0
2220
Encoding: UTF-8
2321
Depends:

NAMESPACE

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export(AbundancePlot)
77
export(ColumnGraphPlot)
88
export(ColumnTreePlot)
99
export(LoadingPlot)
10+
export(PrevalencePlot)
1011
export(RDAPlot)
1112
export(RowGraphPlot)
1213
export(RowTreePlot)
@@ -18,6 +19,7 @@ exportClasses(ColumnGraphPlot)
1819
exportClasses(ColumnTreePlot)
1920
exportClasses(GraphPlot)
2021
exportClasses(LoadingPlot)
22+
exportClasses(PrevalencePlot)
2123
exportClasses(RDAPlot)
2224
exportClasses(RowGraphPlot)
2325
exportClasses(RowTreePlot)
@@ -58,9 +60,12 @@ importFrom(methods,is)
5860
importFrom(methods,new)
5961
importFrom(methods,slot)
6062
importFrom(mia,taxonomyRanks)
63+
importFrom(miaViz,plotAbundance)
64+
importFrom(miaViz,plotAbundanceDensity)
6165
importFrom(miaViz,plotColGraph)
6266
importFrom(miaViz,plotColTree)
6367
importFrom(miaViz,plotLoadings)
68+
importFrom(miaViz,plotPrevalence)
6469
importFrom(miaViz,plotRowGraph)
6570
importFrom(miaViz,plotRowTree)
6671
importFrom(miaViz,plotScree)

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ Changes in version 1.1.X
1717
* Added typical tree operations
1818
* Created GraphPlot family
1919
* Added ScreePlot panel
20+
* Added PrevalencePlot panel

R/AllClasses.R

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,9 @@ setClass("AbundanceDensityPlot", contains="Panel", slots=c(layout="character",
7878
order_descending="logical", dots_shape="character",
7979
dots_shape_by="character"))
8080

81+
#' @rdname PrevalencePlot
82+
#' @export
83+
setClass("PrevalencePlot", contains="Panel", slots=c(detection="numeric",
84+
prevalence="numeric", assay.type="character", rank="character",
85+
include.lowest="logical", show.rank="logical"))
86+

R/class-AbundanceDensityPlot.R

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ setMethod(".defineDataInterface", "AbundanceDensityPlot",
9292

9393
panel_name <- .getEncodedName(x)
9494

95-
list(.selectInput.iSEE(x, field="assay.type", label="Assay type",
95+
list(.selectInput.iSEE(x, field="assay.type", label="Assay type:",
9696
choices=assayNames(se), selected=slot(x, "assay.type")),
9797
# Number of taxa
98-
.numericInput.iSEE(x, field="n", label="Number of taxa",
98+
.numericInput.iSEE(x, field="n", label="Number of taxa:",
9999
value=slot(x, "n"), min=1, max=nrow(se), step=1),
100100

101101
.checkboxInput.iSEE(x, field="flipped", label="Switch axes",
@@ -130,9 +130,9 @@ setMethod(".createObservers", "AbundanceDensityPlot",
130130
callNextMethod()
131131
panel_name <- .getEncodedName(x)
132132

133-
.createProtectedParameterObservers(panel_name,
134-
c("layout", "assay.type", "n", "add_legend", "flipped", "order_descending"),
135-
input=input, pObjects=pObjects, rObjects=rObjects)
133+
.createProtectedParameterObservers(panel_name, c("layout", "assay.type",
134+
"n", "add_legend", "flipped", "order_descending"), input=input,
135+
pObjects=pObjects, rObjects=rObjects)
136136

137137
.createUnprotectedParameterObservers(panel_name,
138138
c("dots_colour", "dots_colour_by", "dots_shape", "dots_shape_by"),
@@ -154,7 +154,7 @@ setMethod(".defineOutput", "AbundanceDensityPlot", function(x) {
154154
color=.panelColor(x))
155155
})
156156

157-
#' @importFrom miaViz plotRowTree
157+
#' @importFrom miaViz plotAbundanceDensity
158158
setMethod(".generateOutput", "AbundanceDensityPlot",
159159
function(x, se, all_memory, all_contents) {
160160

R/class-AbundancePlot.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ setMethod(".defineOutput", "AbundancePlot", function(x) {
134134
height = paste0(slot(x, "PanelHeight"), "px")), color=.panelColor(x))
135135
})
136136

137-
#' @importFrom miaViz plotRowTree
137+
#' @importFrom miaViz plotAbundance
138138
setMethod(".generateOutput", "AbundancePlot",
139139
function(x, se, all_memory, all_contents) {
140140

@@ -290,7 +290,7 @@ setMethod(".definePanelTour", "AbundancePlot", function(x) {
290290
collapseBox(paste0(panel_name, "_Visual"),
291291
title="Visual parameters", open=FALSE,
292292
# Rank
293-
.selectInput.iSEE(x, field="rank", label="Rank",
293+
.selectInput.iSEE(x, field="rank", label="Rank:",
294294
choices=taxonomyRanks(se), selected=slot(x, "rank")),
295295
# Colour legend
296296
.checkboxInput.iSEE(x, field="add_legend", label="View legend",

R/class-PrevalencePlot.R

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
#' Prevalence plot
2+
#'
3+
#' Prevalence plot of all or agglomerated features in a
4+
#' \code{\link[SummarizedExperiment:SummarizedExperiment-class]{SummarizedExperiment}}
5+
#' object. The panel implements \code{\link[miaViz:plotAbundance]{plotPrevalence}}
6+
#' to generate the plot.
7+
#'
8+
#' @section Slot overview:
9+
#' The following slots control the thresholds used in the visualization:
10+
#' \itemize{
11+
#' \item \code{detection} \code{Numeric scalar}. Detection threshold between 0
12+
#' and 1 for absence/presence. (Defualt: \code{0})
13+
#'
14+
#' \item \code{prevalence} \code{Numeric scalar}. Prevalence threshold between 0
15+
#' and 1. The required prevalence is strictly greater by default. To
16+
#' include the limit, set \code{include.lowest} to \code{TRUE}. (Default:
17+
#' \code{0})
18+
#'
19+
#' \item \code{assay.type} \code{Character scalar}. The name of the assay to
20+
#' show. (Default: \code{"relabundance"})
21+
#'
22+
#' \item \code{rank} \code{Character scalar}. The taxonomic rank to visualise.
23+
#' (Default: \code{NULL})
24+
#'
25+
#' \item \code{show.rank} \code{Logical scalar}. Should options for the
26+
#' taxonomic rank appear. (Default: \code{FALSE})
27+
#'
28+
#' \item \code{include.lowest} \code{Logical scalar}. Should features with
29+
#' prevalence equal to \code{prevalence} be included. (Default: \code{FALSE})
30+
#' }
31+
#'
32+
#' In addition, this class inherits all slots from its parent class
33+
#' \code{\link[iSEE:Panel-class]{Panel}}.
34+
#'
35+
#' @return
36+
#' The \code{PrevalencePlot(...)} constructor creates an instance of an
37+
#' PrevalencePlot class, where any slot and its value can be passed to
38+
#' \code{...} as a named argument.
39+
#'
40+
#' @author Giulio Benedetti
41+
#' @examples
42+
#' # Import TreeSE
43+
#' library(mia)
44+
#' data("Tengeler2020", package = "mia")
45+
#' tse <- Tengeler2020
46+
#'
47+
#' tse <- transformAssay(tse,
48+
#' assay.type = "counts",
49+
#' method = "relabundance")
50+
#'
51+
#' # Store panel into object
52+
#' panel <- PrevalencePlot()
53+
#' # View some adjustable parameters
54+
#' head(slotNames(panel))
55+
#'
56+
#' # Launch iSEE with custom initial panel
57+
#' if (interactive()) {
58+
#' iSEE(tse, initial = c(panel))
59+
#' }
60+
#'
61+
#' @docType methods
62+
#' @name PrevalencePlot
63+
NULL
64+
65+
#' @importFrom S4Vectors setValidity2
66+
setValidity2("PrevalencePlot", function(x) {
67+
68+
msg <- character(0)
69+
msg <- .singleStringError(msg, x, fields=c("assay.type", "rank"))
70+
msg <- .validLogicalError(msg, x, fields=c("include.lowest", "show.rank"))
71+
msg <- .validNumberError(msg, x, "detection", lower=0, upper=1)
72+
msg <- .validNumberError(msg, x, "prevalence", lower=0, upper=1)
73+
74+
if( length(msg) ){
75+
return(msg)
76+
}
77+
TRUE
78+
})
79+
80+
#' @importFrom methods callNextMethod
81+
setMethod("initialize", "PrevalencePlot", function(.Object, ...) {
82+
args <- list(...)
83+
args <- .emptyDefault(args, "detection", 0)
84+
args <- .emptyDefault(args, "prevalence", 0)
85+
args <- .emptyDefault(args, "include.lowest", FALSE)
86+
args <- .emptyDefault(args, "assay.type", "relabundance")
87+
args <- .emptyDefault(args, "rank", NA_character_)
88+
args <- .emptyDefault(args, "show.rank", FALSE)
89+
90+
do.call(callNextMethod, c(list(.Object), args))
91+
})
92+
93+
#' @export
94+
#' @importFrom methods new
95+
PrevalencePlot <- function(...) {
96+
new("PrevalencePlot", ...)
97+
}
98+
99+
#' @importFrom methods slot
100+
#' @importFrom SummarizedExperiment assayNames
101+
#' @importFrom mia taxonomyRanks
102+
setMethod(".defineDataInterface", "PrevalencePlot", function(x, se, select_info) {
103+
panel_name <- .getEncodedName(x)
104+
105+
list(.selectInput.iSEE(x, field="assay.type", label="Assay type:",
106+
choices=assayNames(se), selected=slot(x, "assay.type")),
107+
.sliderInput.iSEE(x, field="prevalence", label="Prevalence threshold:",
108+
min=0, max=1, step=0.01, value=slot(x, "prevalence")),
109+
.checkboxInput.iSEE(x, field="include.lowest", label="Include lowest",
110+
value=slot(x, "include.lowest")),
111+
.sliderInput.iSEE(x, field="detection", label="Detection threshold:",
112+
min=0, max=1, step=0.01, value=slot(x, "detection")),
113+
.checkboxInput.iSEE(x, field="show.rank", label="Show rank:",
114+
value=slot(x, "show.rank")),
115+
.conditionalOnCheckSolo(paste0(panel_name, "_show.rank"), TRUE,
116+
.selectInput.iSEE(x, field="rank", label="Rank",
117+
choices=taxonomyRanks(se), selected=slot(x, "rank"))))
118+
})
119+
120+
#' @importFrom methods callNextMethod
121+
setMethod(".defineInterface", "PrevalencePlot", function(x, se, select_info) {
122+
out <- callNextMethod()
123+
list(out[1], .create_visual_box_for_prev_plot(x, se), out[-1])
124+
})
125+
126+
setMethod(".createObservers", "PrevalencePlot",
127+
function(x, se, input, session, pObjects, rObjects) {
128+
129+
callNextMethod()
130+
panel_name <- .getEncodedName(x)
131+
132+
.createProtectedParameterObservers(panel_name, c("assay.type", "prevalence",
133+
"detection", "include.lowest", "rank"), input=input, pObjects=pObjects,
134+
rObjects=rObjects)
135+
136+
.createUnprotectedParameterObservers(panel_name, c("show.rank"),
137+
input=input, pObjects=pObjects, rObjects=rObjects)
138+
139+
invisible(NULL)
140+
})
141+
142+
setMethod(".fullName", "PrevalencePlot", function(x) "Prevalence plot")
143+
setMethod(".panelColor", "PrevalencePlot", function(x) "grey")
144+
145+
#' @importFrom shiny plotOutput
146+
#' @importFrom shinyWidgets addSpinner
147+
setMethod(".defineOutput", "PrevalencePlot", function(x) {
148+
panel_name <- .getEncodedName(x)
149+
150+
addSpinner(plotOutput(panel_name,
151+
height = paste0(slot(x, "PanelHeight"), "px")), color=.panelColor(x))
152+
})
153+
154+
#' @importFrom miaViz plotPrevalence
155+
setMethod(".generateOutput", "PrevalencePlot",
156+
function(x, se, all_memory, all_contents) {
157+
158+
panel_env <- new.env()
159+
all_cmds <- list()
160+
args <- character(0)
161+
162+
all_cmds[["select"]] <- .processMultiSelections(
163+
x, all_memory, all_contents, panel_env
164+
)
165+
166+
if( exists("row_selected", envir=panel_env, inherits=FALSE) ){
167+
panel_env[["se"]] <- se[ , unlist(panel_env[["row_selected"]])]
168+
} else {
169+
panel_env[["se"]] <- se
170+
}
171+
172+
args[["assay.type"]] <- deparse(slot(x, "assay.type"))
173+
args[["prevalence"]] <- deparse(seq(slot(x, "prevalence"), 1, by = 0.1))
174+
args[["detection"]] <- deparse(seq(slot(x, "detection"), 1, by = 0.1))
175+
args[["include.lowest"]] <- deparse(slot(x, "include.lowest"))
176+
177+
if( slot(x, "show.rank") ){
178+
args[["rank"]] <- deparse(slot(x, "rank"))
179+
}
180+
181+
args <- sprintf("%s=%s", names(args), args)
182+
args <- paste(args, collapse=", ")
183+
fun_call <- sprintf("p <- miaViz::plotPrevalence(se, %s)", args)
184+
185+
fun_cmd <- paste(strwrap(fun_call, width = 80, exdent = 4), collapse = "\n")
186+
plot_out <- .textEval(fun_cmd, panel_env)
187+
all_cmds[["fun"]] <- fun_cmd
188+
189+
list(commands=all_cmds, plot=plot_out, varname=NULL, contents=NULL)
190+
})
191+
192+
#' @importFrom shiny renderPlot
193+
#' @importFrom methods callNextMethod
194+
setMethod(".renderOutput", "PrevalencePlot",
195+
function(x, se, output, pObjects, rObjects) {
196+
197+
panel_name <- .getEncodedName(x)
198+
force(se) # defensive programming to avoid bugs due to delayed evaluation
199+
200+
output[[panel_name]] <- renderPlot({
201+
.retrieveOutput(panel_name, se, pObjects, rObjects)
202+
})
203+
204+
callNextMethod()
205+
})
206+
207+
#' @importFrom grDevices pdf dev.off
208+
setMethod(".exportOutput", "PrevalencePlot",
209+
function(x, se, all_memory, all_contents) {
210+
211+
contents <- .generateOutput(x, se, all_memory=all_memory,
212+
all_contents=all_contents)
213+
214+
newpath <- paste0(.getEncodedName(x), ".pdf")
215+
216+
pdf(newpath, width=slot(x, "PanelHeight") / 75,
217+
height=slot(x, "PanelWidth") * 2)
218+
219+
print(contents$plot)
220+
dev.off()
221+
222+
newpath
223+
})
224+
225+
#' @importFrom methods callNextMethod
226+
setMethod(".hideInterface", "PrevalencePlot", function(x, field) {
227+
if( field %in% c("SelectionHistory", "ColumnSelectionRestrict",
228+
"ColumnSelectionDynamicSource", "ColumnSelectionSource") ){
229+
TRUE
230+
} else {
231+
callNextMethod()
232+
}
233+
})
234+
235+
setMethod(".multiSelectionResponsive", "PrevalencePlot",
236+
function(x, dim = character(0)) {
237+
238+
if( "row" %in% dim ){
239+
return(TRUE)
240+
}
241+
return(FALSE)
242+
})
243+
244+
#' @importFrom methods callNextMethod
245+
setMethod(".definePanelTour", "PrevalencePlot", function(x) {
246+
rbind(c(paste0("#", .getEncodedName(x)), sprintf(
247+
"The <font color=\"%s\">Prevalence Plot</font> panel
248+
contains a representation of the relative abundance
249+
for each taxonomic rank. Each column corresponds to
250+
a sample of the <code>SummarizedExperiment</code>
251+
object.", .getPanelColor(x))),
252+
.addTourStep(x, "DataBoxOpen", "The <i>Data parameters</i> box shows the
253+
available parameters that can be tweaked to control the data on
254+
the plot.<br/><br/><strong>Action:</strong> click on this
255+
box to open up available options."),
256+
.addTourStep(x, "Visual", "The <i>Visual parameters</i> box shows
257+
the available visual parameters that can be tweaked in this
258+
plot.<br/><br/><strong>Action:</strong> click on this box to
259+
open up available options."),
260+
callNextMethod())
261+
})
262+
263+
#' @importFrom methods slot
264+
#' @importFrom mia taxonomyRanks
265+
#' @importFrom SummarizedExperiment rowData
266+
.create_visual_box_for_prev_plot <- function(x, se) {
267+
panel_name <- .getEncodedName(x)
268+
269+
# Define what parameters the user can adjust
270+
collapseBox(paste0(panel_name, "_Visual"),
271+
title="Visual parameters", open=FALSE)
272+
}

0 commit comments

Comments
 (0)