Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add plot_granges #6

Closed
wants to merge 44 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ffbeac3
add integrated shiny.gosling plot embedded into vignette, first pass
lee-t May 24, 2024
f3dcd5a
minor labels
lee-t May 28, 2024
b4c4136
Merge branch 'mtmorgan:devel' into vis_shinygosling
lee-t May 28, 2024
1886cb4
update suggests w/shiny.gosling, fix runtime and library calls, updat…
lee-t May 29, 2024
b6a7358
update b_vis vignette. take screenshots for presentation
lee-t Jun 20, 2024
224e5f2
fix knitting error: seperating track objects
lee-t Jun 20, 2024
2aba65e
wrap lolipop plotting in function "plot_shinygosling" examples and ot…
lee-t Jul 29, 2024
7fa6954
Merge branch 'devel' into vis_shinygosling
nturaga Jul 29, 2024
123c788
Remove z_scratch.Rmd after consulting with Tram and Tyronne
nturaga Jul 29, 2024
4bac60a
Remove .Rproj
nturaga Jul 29, 2024
75428d2
Remove d_clinvar.R, fix DESCRIPTION
nturaga Jul 29, 2024
ea6f464
Remove .gosling repo
nturaga Jul 29, 2024
1790d52
revert changes to ignores
nturaga Jul 29, 2024
236aa27
Remove .RData
nturaga Jul 29, 2024
9e9170a
Fixes
nturaga Jul 29, 2024
424fe6b
checks for directory .gosling
tram-nguyen-n Jul 29, 2024
4eefe87
modify function; change colormap, change example, fix categories
lee-t Jul 29, 2024
70ca8d6
edit vignettes; remove gosling.shiny vis from intro, add to alphafold
lee-t Jul 29, 2024
a4a6785
add contributors to DESCRIPTION
lee-t Jul 29, 2024
94837cf
whitespace DESCRIPTION
lee-t Jul 29, 2024
7f44587
no `gosling` R package
lee-t Aug 2, 2024
64e4de0
fixes for example
lee-t Aug 2, 2024
6dfd4b2
rename as_granges->gr, get_range - > g; fix GRanges accesssors in zoo…
lee-t Aug 6, 2024
bbc4def
add validation for input types
lee-t Aug 6, 2024
b9b7388
use cache for gosling dir
lee-t Aug 6, 2024
af48390
add tooltips to lolipop plot
lee-t Aug 6, 2024
96fa7f5
'plot_type' selects between bars and lolipop plots
lee-t Aug 6, 2024
e6137b2
replace tabs with spaces (on Windows-1252)
lee-t Aug 7, 2024
b4a28bb
text and example changes to alphafold.Rmd; fix spelling of 'lollipop'
lee-t Aug 7, 2024
c265cf2
remove runtime from intro
lee-t Aug 7, 2024
00c57a7
sync help page for plot_shinygosling.rd
lee-t Aug 7, 2024
0c66dc9
fixing vignettes, trying to pass R CMD check
lee-t Aug 7, 2024
963a9ff
imports and cache creation reverted
lee-t Aug 7, 2024
008b5d6
reverting importFrom, cache order
lee-t Aug 7, 2024
e32322f
found the missing visual channel imports.
lee-t Aug 7, 2024
48a0558
some message suppression and link fixes
lee-t Aug 21, 2024
916e254
some cosmetics to the gosling section
lgeistlinger Aug 21, 2024
a24edaa
Rename plot_shinygosling to match function. Edit documentation wordin…
lee-t Sep 17, 2024
73f173d
change function indentation and input granges name
lee-t Sep 19, 2024
57cbc97
combine assertions into one `stopifnot()`, `plot_type` is already che…
lee-t Sep 19, 2024
c9e9088
change to use `identical()`
lee-t Sep 19, 2024
c65a351
format example
lee-t Sep 19, 2024
b0b5a45
reformat DESCRIPTION
lee-t Sep 19, 2024
aa46568
change @details
lee-t Sep 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 79 additions & 18 deletions R/plot_shinygosling.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
#' "GRanges Plot".
#' @param subtitle Character string. The subtitle of the plot. Default
#' is "Stacked nucleotide example".
#' @param plot_type Character string. Select the type of gosling plot.
#' Default is "bar"
#' - "bars": Stacked bar plot with height based on pathogenicity score
#' - "lolipop": variation of a bar chart where the bar is replaced with a
#' line and a dot at the end to show mutation variations.
#'
#' @return A Shiny app object that, when run, displays the Gosling
#' plot.
Expand All @@ -45,37 +50,36 @@
plot_granges <-
function(gr,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the indentation when function arguments span more than one line is (also avoid 'cryptic' names where possible)

plot_granges <-
    function(
        granges,
        title = "GRanges Plot",
        subtitle = "Stacked nucleotide example"
    )
{
    ...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

title = "GRanges Plot",
subtitle = "Stacked nucleotide example")
subtitle = "Stacked nucleotide example",
plot_type = "bars")
{
## Validate input
stopifnot(
"Input must be a GRanges or GPos object" =
inherits(gr, c("GRanges", "GPos"))
)
stopifnot(
Copy link
Owner

@mtmorgan mtmorgan Sep 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, combine assertions into a single stopifnot(). Use the S4 is() to test S4 objects (this might require a #' @importFrom methods is); I think the assertion is(granges, "GRanges") is sufficient for your purposes?. The convention in the package uses isScalarCharacter(), along the lines of (check that these are correct with respect to NAandnzchar()`...). I am conservative in use of additional error text, hoping to think that the message is sufficiently clear, or if not clear then encountered commonly enough that the user has figured out how to interpret it (rather than encountering different messages in each package).

stopifnot(
    is(granges, "GRanges"),
    isScalarCharacter(title),
    isScalarCharacter(subtitle),
    isScalarCharacter(plot_type)
)

Actually I think the plot_type test needs to be more explicit -- isScalarCharacter(plot_type) && plot_type %in% <allowable values>.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Option must be a " =
"Title must be a scalar string" =
is.character(title) && length (title) == 1 && !is.na(title) &&
nzchar(title)
)
stopifnot(
"Option must be a " =
"Subtitle must be a scalar string" =
is.character(subtitle) && length (subtitle) == 1 && !is.na(subtitle)
&& nzchar(subtitle)
)



stopifnot(
"Type must be a scalar string" =
is.character(plot_type) && length (plot_type) == 1 && !is.na(plot_type)
&& nzchar(plot_type)
)

## Define categories and color mapping
categories <- c("likely_benign", "ambiguous", "likely_pathogenic")
colormapping <- c("#89d5f5", "gray", "#f56c6c")

## Get range from GRanges object
r <- range(gr)

## This fixes the bug if .gosling directory does not already exist
gosling_cache <- file.path(R_user_dir("AlphaMissenseR", which = "cache"), ".gosling")
if (!dir.exists(cache_dir))

## Prepare track data
track_data <- track_data_gr(
Expand All @@ -84,11 +88,61 @@ plot_granges <-
genomicFields = c("start", "end")
)

## Define tracks
## This fixes the bug if .gosling directory does not already exist
cache_dir <- file.path(tools::R_user_dir("AlphaMissenseR", which = "cache"), ".gosling")
if (!dir.exists(cache_dir))
## TODO: check return value to ensure directory is created successfully
dir.create(cache_dir, recursive = TRUE)

## trigger the option for bars or lolipop
if (plot_type =="bars"){
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As best practice use 'identical(plot_type, "bars"), since this returns TRUE or FALSE, whereas as written this can return cryptic errors if, e.g., plot_typewhere NA or "" (I realize that the checks above ensure that this is not the case, but that does not mean that the better practice of usingidentical()` should be avoided).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#define single track
track_bar <- add_single_track(
width = 800,
height = 180,
data = track_data,
mark = "bar",
x = visual_channel_x(
field = "start", type = "genomic", axis = "bottom"
),
xe = visual_channel_x(field = "end", type = "genomic"),
y = visual_channel_y(
field = "am_pathogenicity", type = "quantitative", axis = "right"
),
color = visual_channel_color(
field = "am_pathogenicity",
type = "quantitative"
),
tooltip = visual_channel_tooltips(
visual_channel_tooltip(field = "REF", type = "nominal",
alt = "Reference"),
visual_channel_tooltip(field = "ALT", type = "nominal",
alt = "Alternative / Mutation"),
visual_channel_tooltip(
field = "am_pathogenicity",
type = "quantitative",
alt = "AM_Pathogenicity Score",
format = "0.2"
) ),
size = list(value = 5)
)

composed_view <- compose_view(
layout = "linear",
xDomain = list(chromosome = as.character(seqnames(r)),
interval = c(start(r), end(r))),
tracks = track_bar

)

## other track
} else if (plot_type == "lolipop"){

## Define multi tracks
track_ref <- add_single_track(
data = track_data,
mark = "rect",
x = visual_channel_x(field = "start", type = "genomic", axis = "bottom"),
x = visual_channel_x(field = "start", type = "genomic", axis = "top"),
xe = visual_channel_x(field = "end", type = "genomic"),
size = list(value = 50),
stroke = "lightgrey",
Expand All @@ -99,9 +153,10 @@ plot_granges <-
track_alt <- add_single_track(
data = track_data,
mark = "point",
x = visual_channel_x(field = "start", type = "genomic", axis = "bottom"),
x = visual_channel_x(field = "start", type = "genomic", axis = "top"),
xe = visual_channel_x(field = "end", type = "genomic"),
y = visual_channel_y(field = "am_class", type = "nominal", axis = "right"),
y = visual_channel_y(field = "am_class", type="nominal",
domain= categories, axis = "left",baseline = "ambiguous" ),
text = list(field = "ALT", type = "nominal"),
size = list(value = 5),
tooltip = visual_channel_tooltips(
Expand All @@ -118,7 +173,7 @@ plot_granges <-
)

## Compose view
composed_view_a <- compose_view(
composed_view <- compose_view(
width = 800,
height = 180,
multi = TRUE,
Expand All @@ -132,17 +187,23 @@ plot_granges <-
field = "am_class",
type = "nominal",
domain = categories,
baseline = "ambiguous",
range = colormapping,
legend = TRUE
),
tracks = add_multi_tracks(track_ref, track_alt)
)

## Arrange view

}
## trigger check
else {
stop("Invalid plot_type. Use 'bars' or 'lolipop'")
}
## Arrange into view
arranged_view3 <- arrange_views(
title = title,
subtitle = subtitle,
views = composed_view_a
views = composed_view
)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm following correctly, I think it would be useful to break this function into two INTERNAL, the first constructing arranged_view3 and the second creating the shiny app. I think there would be value in some sort of sanity check after arranged_view3 has been created that the object is actually sensible -- sort of ensuring that your code has done what it is supposed to do with the inputs and whatever edge cases (e.g., a zero-row GPos) the user of GPos_plot() might provide.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

## Create Shiny app
Expand Down