Skip to content

Instantly share code, notes, and snippets.

@WayneAHof
Created August 14, 2024 22:17
Show Gist options
  • Save WayneAHof/eddf72c11f6b6b008d1e56b88d164b4a to your computer and use it in GitHub Desktop.
Save WayneAHof/eddf72c11f6b6b008d1e56b88d164b4a to your computer and use it in GitHub Desktop.
Sample script to create ggplots incorporating RMSE, MBE and NSE (based on COD method) plus an example of how to create an animated plot and interactive plot
# Libraries ----
library(dplyr)
library(ggplot2) # Plotting data
library(ggrepel) # Prevent overlapping text labels
library(Metrics) # Calculate Statistics
library(plotly) # Interactive plots
library(gganimate) # Animate plots
# Sample Statistical Plots ----
# Create sample data
set.seed(123) # For reproducibility
sample_data <- data.frame(
source = rep(c("Source A", "Source B"), each = 10),
observed_data = c(rnorm(10, mean = 8000, sd = 500), rnorm(10, mean = 8500, sd = 600)),
model_data = c(rnorm(10, mean = 8200, sd = 500), rnorm(10, mean = 8600, sd = 600)),
time = rep(1:10, 2)
)
# Simplified RMSE, NSE, and MBE calculations in one step
metrics_data <- sample_data %>%
group_by(source) %>%
summarise(
rmse = Metrics::rmse(observed_data, model_data),
nse = 1 - sum((model_data - observed_data)^2) / sum((observed_data - mean(observed_data))^2),
mbe = mean(model_data - observed_data)
)
# Determine the range for axes
range_vals <- range(c(sample_data$model_data, sample_data$observed_data))
# Plot the data
ggplot(sample_data, aes(x = model_data, y = observed_data, colour = source)) +
geom_point(size = 4) +
geom_smooth(method = "lm", se = FALSE) +
geom_abline(intercept = 0, slope = 1, linetype = "dashed") +
labs(x = "Modelled Values", y = "Observed Values", colour = "Source") +
geom_text_repel(
data = metrics_data,
aes(x = range_vals[2], y = range_vals[2], label = paste("RMSE:", round(rmse, 2))),
hjust = 1, vjust = 1, direction = "y"
) +
geom_text_repel(
data = metrics_data,
aes(x = range_vals[1], y = range_vals[2], label = paste("NSE:", round(nse, 2))),
hjust = 0, vjust = 1, direction = "y"
) +
geom_text_repel(
data = metrics_data,
aes(x = range_vals[1], y = range_vals[1], label = paste("MBE:", round(mbe, 2))),
hjust = 0, vjust = 0, direction = "y"
) +
coord_equal() +
theme_bw() +
lims(x = range_vals, y = range_vals) +
# ggtitle("Sample Data") +
guides(
colour = guide_legend(override.aes = list(linetype = NA, size = 4)),
shape = guide_legend(override.aes = list(size = 4))
)
# Animated Plotting ----
# Create the ggplot object
p <- ggplot(sample_data, aes(x = observed_data, y = model_data, color = source)) +
geom_point(size = 3) +
labs(
title = "Observed vs. Model Data",
subtitle = "Time: {frame_time}",
x = "Observed Data",
y = "Model Data"
) +
theme_minimal() +
transition_time(time) +
ease_aes("linear")
# Animate the plot
animate(p, nframes = 100, fps = 10, width = 700, height = 700)
# Save the animation as a GIF (optional)
anim_save("observed_vs_model_animation.gif", animation = last_animation())
# Interactive Plotting ----
q <- ggplot(sample_data, aes(x = model_data, y = observed_data, colour = source)) +
geom_point(size = 4) +
geom_smooth(method = "lm", se = FALSE) +
geom_abline(intercept = 0, slope = 1, linetype = "dashed") +
labs(x = "Modelled Values", y = "Observed Values", colour = "Source") +
coord_equal() +
theme_bw() +
lims(x = range_vals, y = range_vals) +
ggtitle("Sample Data") +
guides(
colour = guide_legend(override.aes = list(linetype = NA, size = 4)),
shape = guide_legend(override.aes = list(size = 4))
)
ggplotly(q)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment