如何在ggplot2中用不同变量配置Y轴分组标签?
Got it, let's tackle this Y-axis labeling problem for your tile plot. The core issue is that your plot uses YearMonth for the Y-axis (which we need to keep to maintain vertical spacing for each month) but you want to replace the monthly labels with just the year (2018 and 2019) instead. Here are two reliable solutions:
Solution 1: Show Year Labels at the Start of Each Year
This method places the year label at the first month of each year, hiding all other monthly labels. First, we'll ensure YearMonth is ordered correctly (as a factor) so the plot doesn't jumble the months:
# Ensure YearMonth is ordered properly df$YearMonth <- factor(df$YearMonth, levels = unique(df$YearMonth)) # Get the first month of each year to use as tick positions year_breaks <- tapply(df$YearMonth, df$Year, function(x) x[1]) # Build the plot library(ggplot2) ggplot(df, aes(x = Day, y = YearMonth)) + geom_tile(aes(fill = Total), colour = "white", size = 0.2, na.rm = FALSE) + coord_equal(ratio = 1) + scale_fill_gradient2(low = "#F1EDDE", high = "#C72B26", midpoint = 10) + scale_y_discrete( breaks = year_breaks, # Only place ticks at the first month of each year labels = names(year_breaks), # Use the year as the label expand = c(0, 0) # Remove extra space so tiles fit tight to plot edges ) + labs(y = "Year") # Update Y-axis title to match the new labels
Solution 2: Center Year Labels Between Months
If you prefer the year label to sit centered vertically over all months of that year, we can map YearMonth to a numeric position and calculate the median position for each year:
# Convert YearMonth to a numeric value for precise positioning df$ym_numeric <- as.numeric(factor(df$YearMonth, levels = unique(df$YearMonth))) # Calculate the median position for each year (centers the label) year_center_positions <- tapply(df$ym_numeric, df$Year, median) # Build the plot ggplot(df, aes(x = Day, y = ym_numeric)) + geom_tile(aes(fill = Total), colour = "white", size = 0.2, na.rm = FALSE) + coord_equal(ratio = 1) + scale_fill_gradient2(low = "#F1EDDE", high = "#C72B26", midpoint = 10) + scale_y_continuous( breaks = year_center_positions, # Place ticks at the median position of each year labels = names(year_center_positions), # Use the year as the label expand = c(0, 0), guide = guide_axis(angle = 0) # Keep labels horizontal for readability ) + labs(y = "Year") # Update Y-axis title
Why Your Previous Methods Didn't Work
annotate()adds static text, but it doesn't replace or control the axis ticks/labels.- Using
scale_y_discrete(breaks = df$Year)fails becauseYearisn't the variable mapped to the Y-axis (you're usingYearMonth), so ggplot can't match those values to positions. - Secondary axes are overkill here—you don't need two separate axes, just to override the existing axis's labels.
内容的提问来源于stack exchange,提问作者perkot

