I am looking to plot a geom_line and geom_bar as circular data in R, using the coord_polar line in ggplot. Currently, when I add geom_bar to the geom_line, the geom_line no longer connects to itself. The geom_bar data is the number of counts of an object of interest per hour of the day (24 bins for 24 hours of the day). The time of day is in radians, which needs to be the case due to data processing. The geom_line data is the average value for a climate variable for that hour of the day.
Are there any other workarounds to get the geom_line to connect to itself? I’ve include the full code with simulated data below. The error is in the ggplot section, but perhaps there is something I can do to improve how the bins were created.
library(ggplot2)
library(dplyr)
# Simulate data
n <- 1000
sun.time <- runif(n, 0, 2 * pi)
predictions <- rnorm(n, mean = 3, sd = 0.5)
data_sim <- data.frame(sun.time = sun.time, predictions = predictions)
# bin time into 24 hour bins (one bin per hour)
bins <- 24
data_sim$bins <- cut(data_sim$sun.time, breaks = seq(0, 2 * pi, length.out = bins + 1), include.lowest = TRUE)
# Calculate average predictions for each bin (for geom_line data)
average_predictions <- data_sim %>%
group_by(bins) %>%
summarise(predictions = mean(predictions, na.rm = TRUE))
# Calculate count for each bin
bin_counts <- data_sim %>%
group_by(bins) %>%
summarise(count = n())
# Merge counts and average predictions
bin_counts <- left_join(bin_counts, average_predictions, by = "bins")
# Create labels for the bins (for the geom_bar data)
bin_counts$labels <- seq(0, 2 * pi, length.out = bins + 1)[-length(seq(0, 2 * pi, length.out = bins + 1))]
# Ensure data is ordered by labels
bin_counts <- bin_counts %>% arrange(labels)
# Plot
ggplot(bin_counts, aes(x = labels, y = count)) +
geom_bar(stat = "identity", fill = "skyblue", alpha = 0.7, width = (2 * pi / bins)) +
geom_line(aes(y = predictions * 15), color = "red", size = 1, group = 1) + # Add line for average predictions
coord_polar(start = -0.13) +
theme_minimal() +
scale_x_continuous(expand = c(0, 0), breaks = seq(0, 2 * pi, by = pi / 2),
labels = c('Midnight', 'Sunrise', 'Noon', 'Sunset', 'Midnight')) + # Adjusted labels for clarity
theme(
axis.text.x = element_text(size = 10)
) +
labs(x = '') +
ylim(0, NA)
I understand that I am supposed to add a dummy variable at n+1 equal to 0, to get it to connect, but it ended up just extending the line at x = 0 (midnight), not connecting the value corresponding to bin 24 to bin 1.
fjellrev123 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.