Nothing
#' Visualize Walks
#'
#' @family Visualization Functions
#'
#' @author Antti Lennart Rask
#'
#' @description visualize_walks() visualizes the output of the random walk
#' functions in the RandomWalker package, resulting in one or more ggplot2 plots
#' put together in a patchwork composed of 1 or more patches.
#'
#' @details visualize_walks() generates visualizations of the random walks
#' generated by the random walk functions in the RandomWalker package. These
#' are the functions at the moment of writing:
#' - brownian_motion()
#' - discrete_walk()
#' - geometric_brownian_motion()
#' - random_normal_drift_walk()
#' - random_normal_walk()
#' - rw30()
#'
#' It is possible there are more when you read this, but you can check the rest
#' of the documentation for the current situation.
#'
#' The visualization function is meant to be easy to use. No parameters needed,
#' but you can set `.alpha` if the default value of 0.7 isn't to your
#' liking.
#'
#' You can also choose whether you want the visualization to be interactive or
#' not by setting `.interactive` to TRUE. The function uses the `ggiraph`
#' package for making the patches interactive.
#'
#' If you want to visualize only one of the attributes, you can choose use one of
#' these values (`y`, `cum_sum`, `cum_prod`, `cum_min`, `cum_max`, `cum_mean`) for
#' the `.pluck` parameter.
#'
#' @param .data The input data. Assumed to be created by one of the random walk
#' functions in the RandomWalker package, but can be any data frame or tibble
#' that contains columns `walk_number`, `x`, and one or more numeric columns
#' like `y`, `cum_sum`, `cum_prod`, `cum_min`, `cum_max` and `cum_mean`, for
#' instance.
#' @param .alpha The alpha value for all the line charts in the visualization.
#' Values range from 0 to 1. Default is 0.7.
#' @param .interactive A boolean value. TRUE if you want the patches to be
#' interactive. FALSE if you don't. Default is FALSE.
#' @param .pluck If you want to visualize only one of the You can choose one of
#' the values (`y`, `cum_sum`, `cum_prod`, `cum_min`, `cum_max`, `cum_mean`).
#' Default is FALSE.
#'
#' @return A patchwork composed of 1 or more patches
#'
#' @examples
#' # Generate random walks and visualize the result
#' set.seed(123)
#' rw30() |>
#' visualize_walks()
#'
#' # Set the alpha value to be other than the default 0.7
#' set.seed(123)
#' rw30() |>
#' visualize_walks(.alpha = 0.5)
#'
#' # Use the function with an input that has alternatives for y
#' set.seed(123)
#' random_normal_walk(.num_walks = 5, .initial_value = 100) |>
#' visualize_walks()
#'
#' # Use the function to create interactive visualizations
#' set.seed(123)
#' random_normal_walk(.num_walks = 5, .initial_value = 100) |>
#' visualize_walks(.interactive = TRUE)
#'
#' # Use .pluck to pick just one visualization
#' set.seed(123)
#' random_normal_walk(.num_walks = 5, .initial_value = 100) |>
#' visualize_walks(.pluck = "cum_sum")
#'
#' @name visualize_walks
NULL
#' @rdname visualize_walks
#' @export
visualize_walks <- function(.data, .alpha = 0.7, .interactive = FALSE, .pluck = FALSE) {
# Retrieve the attributes of the data (e.g., function name, number of walks, etc.)
atb <- attributes(.data)
# Function to generate a plot for a given y-variable in the data
generate_plot <- function(y_var) {
# Convert y-label to a more readable format if it's not 'y'
y_label_pretty <- if (y_var == "y") "y" else convert_snake_to_title_case(y_var)
# Create a static ggplot visualization
if (.interactive == FALSE) {
# Create a ggplot object
p <- ggplot2::ggplot(.data, ggplot2::aes(x = x, y = get(y_var), color = walk_number)) +
# Plot lines with some transparency
ggplot2::geom_line(alpha = .alpha) +
# Use a minimal theme
ggplot2::theme_minimal() +
# Remove the legend
ggplot2::theme(legend.position = "none") +
# Set plot labels
ggplot2::labs(title = y_label_pretty, x = "Step", y = NULL)
return(p)
# Create an interactive visualization with ggiraph
} else if (.interactive == TRUE) {
# Add tooltip information to the data
.data <- .data |>
dplyr::mutate(
.tooltip = paste0(
"Walk Number: ", walk_number, " | ",
"Step: ", x, " | ",
y_label_pretty, ": ", round(get(y_var), digits = 3)
)
)
# Create an interactive plot with ggiraph
g <- ggplot2::ggplot(
.data,
ggplot2::aes(
x = x,
y = get(y_var),
color = walk_number,
group = walk_number,
data_id = walk_number,
tooltip = .tooltip
)
) +
# Add interactive lines
ggiraph::geom_line_interactive(alpha = .alpha) +
# Add interactive points
ggiraph::geom_point_interactive(alpha = .alpha, size = 0.1) +
# Use a minimal theme
ggplot2::theme_minimal() +
# Remove the legend
ggplot2::theme(legend.position = "none") +
# Set plot labels
ggplot2::labs(title = y_label_pretty, x = "Step", y = NULL)
return(g)
# Check the .interactive parameter
} else {
rlang::abort(
message = "The parameter `.interactive` must be either TRUE/FALSE",
use_cli_format = TRUE
)
}
}
# Identify variables to plot, excluding 'walk_number' and 'x'
plot_vars <- setdiff(atb$names, c("walk_number", "x"))
# Generate a list of plots for each variable in plot_vars
plots <- lapply(plot_vars, generate_plot)
# Generate a subtitle based on the function name in attributes
.subtitle <- paste0("Function: ", if (atb$fns == "rw30") "rw30" else convert_snake_to_title_case(atb$fns))
# Generate the plot caption dynamically based on attributes
.caption <- generate_caption(atb)
# Define annotations (title, subtitle, caption) for the combined plot
plot_annotations <- patchwork::plot_annotation(
title = paste0(atb$num_walks, " Random Walks"),
subtitle = .subtitle,
caption = .caption
)
# Define theme adjustment for the combined plot (applicable in interactive mode)
plot_theme <- ggplot2::theme(
plot.caption = ggplot2::element_text(hjust = 1, margin = ggplot2::margin(t = 0, r = 0, b = 0, l = 0)),
plot.margin = ggplot2::margin(t = 10, r = 10, b = 0, l = 10)
)
# Handle the `.pluck` option for selecting a specific plot
if (.pluck != FALSE) {
.pluck_n <- switch(
.pluck,
"y" = 1,
"cum_sum" = 2,
"cum_prod" = 3,
"cum_min" = 4,
"cum_max" = 5,
"cum_mean" = 6,
rlang::abort(
message = "Invalid parameter value for `.pluck`",
use_cli_format = TRUE
)
)
# Return the plucked plot with annotations
plucked_plot <- plots[[.pluck_n]] + plot_annotations
# If interactive, return the interactive version of the plucked plot
if (.interactive == TRUE) {
return(
ggiraph::girafe(
ggobj = plucked_plot + plot_theme,
options = list(
ggiraph::opts_hover(css = "stroke:black;stroke-width:2pt;"),
ggiraph::opts_hover_inv(css = "opacity:0.4;"),
ggiraph::opts_toolbar(position = "topright"),
ggiraph::opts_tooltip(
offx = 200,
offy = 5,
use_cursor_pos = FALSE,
opacity = 0.7
),
ggiraph::opts_zoom(max = 5)
)
)
)
}
return(plucked_plot)
}
# Patchwork for the default version of the visualization
if (.interactive == FALSE) {
# Combine the individual plots into a single plot, or return the single plot with annotations
combined_plot <- if (length(plots) > 1) {
patchwork::wrap_plots(plots) + plot_annotations
} else {
plots[[1]] + plot_annotations
}
return(combined_plot)
# Patchwork for the interactive version of the visualization
} else {
# Define plot options for ggiraph
plot_options <- list(
# Customize hover effect
ggiraph::opts_hover(css = "stroke:black;stroke-width:2pt;"),
# Customize hover-out effect
ggiraph::opts_hover_inv(css = "opacity:0.4;"),
# Place toolbar on top right
ggiraph::opts_toolbar(position = "topright"),
# Customize tooltip
ggiraph::opts_tooltip(offx = 200, offy = 5, use_cursor_pos = FALSE, opacity = 0.7),
# Enable zoom
ggiraph::opts_zoom(max = 5)
)
# Combine plots using patchwork for interactive visualization
combined_plot <- if (length(plots) > 1) {
ggiraph::girafe(
ggobj = patchwork::wrap_plots(plots) + plot_annotations + plot_theme,
options = plot_options
)
} else {
ggiraph::girafe(
ggobj = plots[[1]] + plot_annotations + plot_theme,
options = plot_options
)
}
return(combined_plot)
}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.