#' Produce a scatter plot of x/y points. If x is a categorical/factor variable then its levels with respect to y
#' can be plotted in separate aligned panels or overlapped with different point colors.
#'
#'
#' Function returns a plot object of x/y scatter points where the x variable can possibly be a category/factor
#' type variable.
#'
#'
#' @param df The target data frame from which the scatter points are plotted.
#' @param aes_x A string that sets the x axis variable name from \code{df}.
#' @param aes_y A string that sets the y axis variable name from \code{df}.
#' @param title A string that sets the overall title.
#' @param subtitle A string that sets the overall subtitle.
#' @param x_label A string that sets the x axis title.
#' @param y_label A string that sets the y axis title.
#' @param x_limits A numeric vector that sets the minimum, maximum, and interval for the x axis.
#' @param y_limits A numeric vector that sets the minimum, maximum, and interval for the y axis.
#' @param pts_color A string that sets the color of the points.
#' @param pts_alpha A numeric value that sets the alpha level of \code{pts_color}.
#' @param pts_size A numeric value that sets the size of the points.
#' @param factor_var A string that sets the factor variable that has multiple levels from \code{df}.
#' @param factor_levels A character vector that sets the levels to be plotted from \code{factor_var}.
#' @param factor_colors A character vector that sets the colors for each of the values in \code{factor_levels}.
#' @param factor_level_panels A logical that if \code{TRUE} will draw the levels of \code{factor_var} in separate panels.
#' Otherwise all levels of \code{factor_var} will plot on a single x axis with different colors.
#' @param n_rows An integer that defines the number of panel rows if \code{factor_level_panels} is \code{TRUE}.
#' @param n_cols An integer that defines the number of panel columns if \code{factor_level_panels} is \code{TRUE}.
#' @param connect A string that sets the variable from \code{df} that will connect its values as a line across \code{aes_x}.
#' @param connect_color A string that sets the color of the connect line.
#'
#'
#' @import ggplot2
#' @import patchwork
#' @import magrittr
#' @import purrr
#' @import scales
#' @import dplyr
#'
#' @return A plot object.
#'
#' @author Rick Dean
#'
#' @export
#'
scatter_plot <- function(
df,
aes_x,
aes_y,
title = NULL,
subtitle = NULL,
x_label = aes_x,
y_label = aes_y,
x_limits = c(0,10,1),
y_limits = c(0,10,1),
pts_color = "black",
pts_alpha = 1.0,
pts_size = 1,
factor_var = NULL,
factor_levels = NULL,
factor_colors = NULL,
factor_level_panels = FALSE,
n_rows = 1,
n_cols = length(factor_levels),
connect = NULL,
connect_color = "red"){
if(!is.null(factor_var) && factor_level_panels){
plots <- map(factor_levels, function(factor_level){
p1 <- filter(df, !!sym(factor_var) == factor_level) %>%
ggplot(aes_string(x = aes_x, y = aes_y)) +
geom_point(color = pts_color, alpha = pts_alpha, size = pts_size) +
theme(
panel.background = element_rect(fill = "white", color = "black"),
panel.grid.major = element_line(size = 0.5, linetype = "solid", color = "gray"),
panel.grid.minor = element_line(size = 0.5, linetype = "solid", color = "gray"),
axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
axis.title.y = element_blank()) +
labs(title = factor_level, x = x_label, y = NULL) +
scale_x_continuous(
breaks = seq(x_limits[[1]], x_limits[[2]],by=x_limits[[3]]),
limits = c(x_limits[[1]], x_limits[[2]]),
oob = rescale_none) +
scale_y_continuous(
breaks = seq(y_limits[[1]], y_limits[[2]],by=y_limits[[3]]),
limits = c(y_limits[[1]], y_limits[[2]]),
oob = rescale_none)
p1
})
plots[[1]] <- plots[[1]] +
labs(y = y_label ) +
theme(
axis.text.y = element_text(color = "black"),
axis.ticks.y = element_line(size = 1),
axis.title.y = element_text(color = "black", angle = 90),
)
all_plots <- plots[[1]]
for(i in 2:length(plots)){
all_plots <- all_plots + plots[[i]]
}
all_plots <- all_plots + plot_layout(nrow = n_rows, ncol = n_cols) +
plot_annotation(title = title, subtitle = subtitle)
}else if(!is.null(factor_var)) {
all_plots <- ggplot(df, aes_string(x = aes_x, y = aes_y, color = factor_var)) +
geom_point(alpha = pts_alpha, size = pts_size) +
labs(title = title, subtitle = subtitle, x = x_label, y = y_label ) +
theme(
panel.background = element_rect(fill = "white", color = "black"),
panel.grid.major = element_line(size = 0.5, linetype = "solid", color = "gray"),
panel.grid.minor = element_line(size = 0.5, linetype = "solid", color = "gray"),
axis.text.y = element_text(color = "black"),
axis.ticks.y = element_line(size = 1),
axis.title.y = element_text(color = "black", angle = 90),
legend.position = "top"
) +
scale_x_continuous(
breaks = seq(x_limits[[1]], x_limits[[2]],by=x_limits[[3]]),
limits = c(x_limits[[1]], x_limits[[2]]),
oob = rescale_none) +
scale_y_continuous(
breaks = seq(y_limits[[1]], y_limits[[2]],by=y_limits[[3]]),
limits = c(y_limits[[1]], y_limits[[2]]),
oob = rescale_none) +
scale_color_manual(values = factor_colors)
}else {
all_plots <- ggplot(df, aes_string(x = aes_x, y = aes_y)) +
geom_point(color = pts_color, alpha = pts_alpha, size = pts_size) +
labs(title = title, subtitle = subtitle, x = x_label, y = y_label ) +
theme(
panel.background = element_rect(fill = "white", color = "black"),
panel.grid.major = element_line(size = 0.5, linetype = "solid", color = "gray"),
panel.grid.minor = element_line(size = 0.5, linetype = "solid", color = "gray"),
axis.text.y = element_text(color = "black"),
axis.ticks.y = element_line(size = 1),
axis.title.y = element_text(color = "black", angle = 90),
) +
scale_x_continuous(
breaks = seq(x_limits[[1]], x_limits[[2]],by=x_limits[[3]]),
limits = c(x_limits[[1]], x_limits[[2]]),
oob = rescale_none) +
scale_y_continuous(
breaks = seq(y_limits[[1]], y_limits[[2]],by=y_limits[[3]]),
limits = c(y_limits[[1]], y_limits[[2]]),
oob = rescale_none)
if(!is.null(connect)){
all_plots <- all_plots +
geom_line(data = df, aes_string(x = aes_x, y = connect), color = connect_color)
}
}
all_plots
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.