如何在ggplot中用geom_text仅标记每年第一季度的年份?
解决ggplot仅标注每年第一季度数据点年份的问题
问题需求
需要在ggplot结合geom_point和geom_text时,仅为每年第一季度的数据点标注年份,其余季度不显示标签(呈现类似2009 + + + 2010 + + + 2011的效果),且需通过程序化方式实现,适配多数据集和多年数据。当前代码会给所有数据点添加日期标签,不符合需求。
解决方案
核心思路是在数据预处理阶段生成一个仅第一季度显示年份的标签列,而非直接使用原日期字段作为标签:
- 用
lubridate包的quarter()函数判断日期是否为第一季度 - 仅对第一季度的行提取年份作为标签,其余行设为空字符串
- 在
geom_text中使用该标签列,空字符串会自动不显示标签
修改后的完整代码
library(tidyverse) library(pxweb) library(lubridate) library(janitor) # 从瑞典统计局下载数据 # PXWEB 查询 pxweb_query_list <- list("Kon"=c("1+2"), "Alder"=c("tot16-64"), "Arbetskraftstillh"=c("ALÖS"), "ContentsCode"=c("0000062S"), "Tid"=c("*")) # 下载失业率数据 unemp <- pxweb_get(url = "https://api.scb.se/OV0104/v1/doris/en/ssd/AM/AM0403/AM0403A/NAKUBefolkning2KTD", query = pxweb_query_list) # 转换为数据框 unemp <- as.data.frame(unemp, column.name.type = "text", variable.value.type = "text") # PXWEB 查询职位空缺率 pxlist2 <- list("Antanstallda"=c("TOT"), "ContentsCode"=c("AM0701F4"), "Tid"=c("*")) vacancy <- pxweb_get(url = "https://api.scb.se/OV0104/v1/doris/en/ssd/AM/AM0701/AM0701D/KVRekVakStor", query = pxlist2) # 转换为数据框 vacancy <- as.data.frame(vacancy, column.name.type = "text", variable.value.type = "text") rm(pxlist2, pxweb_query_list) # 修正日期格式 unemp$quarter <- yq(unemp$quarter) vacancy$quarter <- yq(vacancy$quarter) # 合并数据集 final <- inner_join(unemp, vacancy, by = "quarter") # 清理列名 final <- final %>% janitor::clean_names() # 数据整理 + 生成仅第一季度显示的年份标签 final <- final %>% mutate(unemp = percent) %>% mutate(date = quarter) %>% select(date, unemp, vacancy_rate) %>% # 新增标签列:仅第一季度显示年份,其余为空 mutate(year_label = ifelse(quarter(date) == 1, as.character(year(date)), "")) %>% # 划分时间段 mutate(period = case_when( date>=ymd('2002-04-01') & date<ymd('2008-01-01') ~ "one", date>=ymd('2008-01-01') & date<=ymd('2015-01-01') ~ "two")) # 绘制图表 ggplot(final) + aes(x = unemp, y = vacancy_rate, group = period, color = period, label = year_label) + # 使用新的标签列 geom_point() + geom_path() + geom_text(nudge_x = 0.1, nudge_y = 0.1) + # 微调标签位置避免遮挡点 facet_wrap(~period) + theme_gray()
效果说明
修改后,图表仅会在每年第一季度的数据点旁显示对应年份,其余季度的点无标签,完全符合需求,且全程程序化处理,无需手动指定年份,可直接适配其他包含季度日期的数据集。
内容的提问来源于stack exchange,提问作者Tomas R
相关产品推荐
相关产品推荐

