rggplot2rose-plot

Rose diagram plot in R with cardina directions does not plot north sector


The following simulation illustrates the problem - for some reason (presumably because the polygon spans 0 / 2pi) the north polygon in this rose diagram is not plotting. I can't work out how to resolve this and any pointers would be welcome!

set.seed(456)

# Define aspects
aspects <- c("North", "Northeast", "East", "Southeast", "South", "Southwest", "West", "Northwest")

# Number of measurements per aspect
n_measurements <- 10

# Create a vector of all aspects (repeated for each measurement)
all_aspects <- rep(aspects, each = n_measurements)

# Simulate percent cover data (with some variation based on aspect)
# Example: South-facing might have higher lichen cover due to sun exposure
mean_cover <- c(40, 35, 30, 45, 50, 42, 38, 33) # Example means for each aspect
sd_cover <- 10 # Standard deviation for random variation

all_cover <- rnorm(length(all_aspects), mean = rep(mean_cover, each = n_measurements), sd = sd_cover)

# Create a data frame
lichen_data <- data.frame(aspect = all_aspects, cover = all_cover)

# **Order the factor levels for plotting**
lichen_data$aspect <- factor(lichen_data$aspect, levels = aspects)

# Calculate mean and standard error for each aspect
mean_cover_by_aspect <- tapply(lichen_data$cover, lichen_data$aspect, mean)
se_cover_by_aspect <- tapply(lichen_data$cover, lichen_data$aspect, function(x) sd(x) / sqrt(length(x)))

# Convert aspects to angles in radians for the rose diagram
angles <- seq(0, 2*pi - pi/4, by = pi/4)  # Angles for each aspect

# Create data frame for plotting
rose_data <- data.frame(aspect = aspects,
                        cover = mean_cover_by_aspect[aspects],
                        angle = angles,
                        se = se_cover_by_aspect[aspects])

# Create the rose diagram with error bars
library(ggplot2)

ggplot(rose_data, aes(x = angle, y = cover)) +
  geom_bar(stat = "identity", width = pi/4, color = "black", fill = "lightblue") +
  geom_errorbar(aes(ymin = cover - se, ymax = cover + se), width = 0.1) + # Add error bars
  coord_polar()+#start = 0) +
  scale_x_continuous(limits = c(0, 2*pi),
                     breaks = angles,
                     labels = aspects) +
  scale_y_continuous(limits = c(0, max(rose_data$cover + rose_data$se) * 1.1)) + # Adjust y-axis limits
  labs(title = "Lichen Cover by Aspect (Rose Diagram)",
       y = "Mean Lichen Percent Cover") +
  theme_minimal() +
  theme(axis.text.x = element_text(size = 10),
        axis.title.x = element_blank(),
        axis.title.y = element_text(size = 12))


Solution

  • Moving my comment to an answer. Here's a quick fix:

    I suspect there is a more concise ({ggplot2}-like) way to achieve what you are after. Let's see if an expert adds one.

     library(ggplot2)
     ggplot(rose_data, aes(x = angle, y = cover)) +
       geom_bar(stat = "identity", width = pi/4, color = "black", fill = "lightblue") +
       geom_errorbar(aes(ymin = cover - se, ymax = cover + se), width = 0.1) + 
       coord_polar(start = angles[length(angles)]/2-pi) +
       scale_x_continuous(breaks = angles, labels = aspects) +
       scale_y_continuous(limits = c(0, max(rose_data$cover + rose_data$se) * 1.1)) + 
       labs(title = "Lichen Cover by Aspect (Rose Diagram)",
            y = "Mean Lichen Percent Cover") +
       theme_minimal() +
       theme(axis.text.x = element_text(size = 10),
             axis.title.x = element_blank(),
             axis.title.y = element_text(size = 12))