ubigen/R/plots.R

332 lines
7.7 KiB
R
Raw Permalink Normal View History

2022-05-30 20:08:54 +02:00
#' Create a plot showing an overview over the provided ranking.
#'
#' @param ranked_data The ranking to visualize.
2022-05-30 21:27:18 +02:00
#' @param highlighted_genes Genes that will be marked.
2022-05-30 20:08:54 +02:00
#' @param sample_proportion Proportion of rows to use as the shown sample.
#'
#' @return A `plotly` figure.
2022-11-30 15:27:00 +01:00
#'
#' @export
2022-05-30 21:27:18 +02:00
overview_plot <- function(ranked_data,
highlighted_genes = NULL,
sample_proportion = 0.05) {
figure <- plotly::plot_ly() |>
2022-05-30 20:08:54 +02:00
plotly::add_lines(
data = ranked_data[sample(
nrow(ranked_data),
sample_proportion * nrow(ranked_data)
)],
2022-06-22 20:23:48 +02:00
x = ~percentile,
2022-05-30 21:27:18 +02:00
y = ~score,
2022-12-16 11:31:30 +01:00
line = list(color = base_color()),
2022-05-30 21:27:18 +02:00
hoverinfo = "skip"
2022-05-30 20:08:54 +02:00
) |>
plotly::layout(
2022-06-22 20:23:48 +02:00
xaxis = list(
title = "Percentile",
tickformat = ".1%"
),
yaxis = list(title = "Score"),
shapes = list(
vline(0.95),
vline(0.75),
vline(0.50),
vline(0.25),
vline(0.05)
),
annotations = list(
vlineannotation(0.95),
vlineannotation(0.75),
vlineannotation(0.50),
vlineannotation(0.25),
vlineannotation(0.05)
)
2022-05-30 20:08:54 +02:00
)
2022-05-30 21:27:18 +02:00
2022-05-30 21:59:40 +02:00
if (length(highlighted_genes) > 0) {
2022-05-30 21:27:18 +02:00
figure <- figure |>
plotly::add_markers(
data = ranked_data[gene %chin% highlighted_genes],
2022-06-22 20:23:48 +02:00
x = ~percentile,
2022-05-30 21:27:18 +02:00
y = ~score,
text = ~ glue::glue(
"<b>{hgnc_name}</b><br>",
"Score: {round(score, digits = 2)}<br>",
"Rank: {rank}<br>",
"Percentile: {round(percentile * 100, digits = 2)}%"
),
2022-12-16 11:31:30 +01:00
marker = list(color = highlight_color()),
2022-05-30 21:27:18 +02:00
hoverinfo = "text",
showlegend = FALSE
)
}
figure
2022-05-30 20:08:54 +02:00
}
2022-05-30 21:59:40 +02:00
#' Create a plot comparing some genes with the overall ranking.
#'
#' @param ranked_data The ranking to visualize.
#' @param highlighted_genes Genes that will be compared.
#'
#' @return A `plotly` figure.
2022-11-30 15:27:00 +01:00
#'
#' @export
2022-05-30 21:59:40 +02:00
box_plot <- function(ranked_data, highlighted_genes) {
2022-12-16 11:31:30 +01:00
fig <- plotly::plot_ly() |>
2022-05-30 21:59:40 +02:00
plotly::add_boxplot(
2022-12-16 11:31:30 +01:00
data = ranked_data[!gene %chin% highlighted_genes],
2022-05-30 21:59:40 +02:00
x = ~score,
2022-12-16 11:31:30 +01:00
y = "Other genes",
line = list(color = base_color()),
fillcolor = transparent(base_color()),
showlegend = FALSE,
2022-05-30 21:59:40 +02:00
boxpoints = FALSE
)
2022-12-16 11:31:30 +01:00
if (length(highlighted_genes) >= 1) {
fig <- fig |> plotly::add_boxplot(
data = ranked_data[gene %chin% highlighted_genes],
x = ~score,
y = "Your genes",
line = list(color = highlight_color()),
fillcolor = transparent(highlight_color()),
showlegend = FALSE,
boxpoints = FALSE
)
}
fig |> plotly::layout(
xaxis = list(title = "Score"),
yaxis = list(title = "")
)
2022-05-30 21:59:40 +02:00
}
2022-05-30 20:08:54 +02:00
#' Create plot showing the distribution of scores using `plotly`.
#'
#' @param ranked_data Data on genes with precomputed ranks.
2022-05-30 21:27:18 +02:00
#' @param highlighted_genes Genes that will be marked.
2022-05-30 20:08:54 +02:00
#' @param ranks How may ranks the x-axis should include. If this parameter is
#' `NULL`, all ranks will be shown.
#'
#' @return A `plotly` figure for rendering.
2022-12-16 11:31:30 +01:00
#'
2022-11-30 15:27:00 +01:00
#' @export
2022-05-30 21:27:18 +02:00
scores_plot <- function(ranked_data, highlighted_genes = NULL, ranks = 1000) {
2022-05-30 20:08:54 +02:00
data <- if (is.null(ranks)) {
ranked_data
} else {
ranked_data[1:ranks]
}
ranks_label <- if (is.null(ranks)) {
"Ranks"
} else {
glue::glue("Ranks (1 to {ranks})")
}
2022-05-30 21:27:18 +02:00
data[, group := data.table::fifelse(
gene %chin% highlighted_genes,
"Your genes",
"All genes"
)]
2022-12-16 11:31:30 +01:00
data[, color := data.table::fifelse(
gene %chin% highlighted_genes,
highlight_color(),
base_color()
)]
data[, size := data.table::fifelse(
gene %chin% highlighted_genes,
8,
4
)]
# Draw "Your genes" on top of "All genes".
setorder(data, group)
2022-05-30 20:08:54 +02:00
plotly::plot_ly() |>
plotly::add_markers(
data = data,
x = ~rank,
y = ~score,
2022-05-30 21:27:18 +02:00
name = ~group,
text = ~ glue::glue(
"<b>{hgnc_name}</b><br>",
"Score: {round(score, digits = 2)}<br>",
"Rank: {rank}<br>",
"Percentile: {round(percentile * 100, digits = 2)}%"
),
2022-12-16 11:31:30 +01:00
marker = ~ list(
color = color,
size = size,
opacity = 1,
line = list(width = 0)
),
2022-05-30 21:27:18 +02:00
hoverinfo = "text",
showlegend = FALSE
2022-05-30 20:08:54 +02:00
) |>
plotly::layout(
2022-07-13 18:32:26 +02:00
xaxis = list(
title = ranks_label,
autorange = "reversed"
),
2022-05-30 20:08:54 +02:00
yaxis = list(title = "Score"),
clickmode = "event+select",
dragmode = "select"
)
}
2022-06-22 20:23:48 +02:00
2024-04-26 20:52:45 +02:00
#' Create a scatter plot for comparing two different rankings.
#'
#' @param ranking_x The ranking to be shown on the X-axis.
#' @param ranking_y The ranking to be shown on the Y-axis.
#' @param label_x Axis title for the X-axis.
#' @param label_y Axis title for the Y-axis.
#' @param highlighted_genes Gene IDs for genes that should be highlighted
#' @param use_percentiles Display percentiles instead of scores.
#'
#' @return A `plotly` figure for rendering.
#'
#' @export
rankings_comparison_plot <- function(ranking_x,
ranking_y,
label_x = "Ranking X",
label_y = "Ranking Y",
highlighted_genes = NULL,
use_percentiles = FALSE) {
data <- merge(
ranking_x[, .(gene, score, percentile)],
ranking_y[, .(gene, score, percentile)],
by = "gene",
suffixes = c(x = "_x", y = "_y")
)
data <- merge(
data,
ubigen::genes,
by = "gene"
)
data[, group := data.table::fifelse(
gene %chin% highlighted_genes,
"Your genes",
"All genes"
)]
data[, color := data.table::fifelse(
gene %chin% highlighted_genes,
highlight_color(),
base_color()
)]
data[, size := data.table::fifelse(
gene %chin% highlighted_genes,
8,
4
)]
# Draw "Your genes" on top of "All genes".
setorder(data, group)
plotly::plot_ly() |>
plotly::add_markers(
data = data,
x = if (use_percentiles) ~percentile_x else ~score_x,
y = if (use_percentiles) ~percentile_y else ~score_y,
name = ~group,
marker = ~ list(
color = color,
size = size,
opacity = 1,
line = list(width = 0)
),
text = ~hgnc_name,
hoverinfo = "text",
customdata = ~gene,
showlegend = FALSE
) |>
plotly::layout(
xaxis = list(
title = label_x,
tickformat = if (use_percentiles) ".1%" else NULL
),
yaxis = list(title = label_y),
shapes = list(
vline(0.5),
hline(0.5)
),
clickmode = "event+select",
dragmode = "lasso"
)
}
2022-06-22 20:23:48 +02:00
#' Helper function for creating a vertical line for plotly.
#' @noRd
vline <- function(x) {
list(
type = "line",
y0 = 0,
y1 = 1,
yref = "paper",
x0 = x,
x1 = x,
line = list(
color = "#00000080",
opacity = 0.5,
dash = "dot"
)
)
}
2024-04-26 20:52:45 +02:00
#' Helper function for creating a horizontal line for plotly.
#' @noRd
hline <- function(y) {
list(
type = "line",
y0 = y,
y1 = y,
x0 = 0,
x1 = 1,
xref = "paper",
line = list(
color = "#00000080",
opacity = 0.5,
dash = "dot"
)
)
}
2022-06-22 20:23:48 +02:00
#' Helper function for creating annotations for lines created using [vline()].
#' @noRd
vlineannotation <- function(x) {
list(
text = glue::glue("{round(x * 100)}%"),
showarrow = FALSE,
yref = "paper",
x = x,
y = 1,
xanchor = "left",
xshift = 4,
align = "left",
font = list(
color = "#00000080"
)
)
}
2022-12-16 11:31:30 +01:00
#' Base color for plots.
#' @noRd
base_color <- function() "#7d19bf"
#' Highlight color for plots.
#' @noRd
highlight_color <- function() "#ff7f2a"
#' Return the half-transparent version of the color.
#' @noRd
transparent <- function(color) {
paste0(color, "80")
}