为ggplot速度图添加长度对应速度值的键形(glyph)图例
实现方案
你原有代码中的日期转换逻辑存在错误,先修正该问题后,可通过以下两种方式实现对应速度值的箭头图例:
方案1:使用metR包(推荐,原生支持矢量长度图例)
metR包的geom_arrow专门针对速度/矢量类可视化设计,可自动生成和速度值匹配的长度图例,可直接指定图例参考值为你需要的5 m/s或0.5 m/s:
# 安装依赖包(首次使用运行) # install.packages(c("ggplot2", "metR", "lubridate", "scales")) library(ggplot2) library(metR) library(lubridate) library(scales) # 构造数据 Speed <- c(24, 23, 23, 24, 26, 27, 27, 27, 26, 24) Dir <- c(108, 105, 103, 100, 97, 96, 97, 99, 101, 103) Date <- c('2016-08-01', '2016-08-02', '2016-08-03', '2016-08-04', '2016-08-05', '2016-08-06', '2016-09-07', '2016-09-08', '2016-09-09', '2016-09-10') DF <- data.frame(Speed, Dir, Date) # 修正日期转换逻辑 DF$Date <- as.Date(DF$Date) # 计算矢量终点坐标 DF$xend <- DF$Date + DF$Speed * 1 * cos((90 - DF$Dir) / 360 * 2 * pi) DF$yend <- DF$Speed * 1 * sin((90 - DF$Dir) / 360 * 2 * pi) # 绘图 ggplot(DF) + # 绘制速度矢量 geom_arrow(aes(x = Date, y = 0, dx = xend - Date, dy = yend - 0, col = factor(Date)), arrow.length = unit(0.5, "cm")) + # 基准点 geom_point(aes(Date, 0), size = 1) + # 配置长度图例,这里设置参考值为5 m/s,可修改为0.5适配你的数据标度 scale_length(name = "速度 (m/s)", breaks = 5) + scale_x_date(labels = date_format('%b'), breaks = date_breaks('1 month')) + coord_fixed(1) + # 可保留日期颜色图例,不需要的话加scale_color_discrete(guide = "none") theme_minimal()
方案2:手动添加注释图例(无需额外安装扩展包)
如果你不想安装新的扩展包,可以直接在绘图角落手动添加自定义箭头作为图例:
library(ggplot2) library(lubridate) library(scales) # 数据构造部分和方案1一致 Speed <- c(24, 23, 23, 24, 26, 27, 27, 27, 26, 24) Dir <- c(108, 105, 103, 100, 97, 96, 97, 99, 101, 103) Date <- c('2016-08-01', '2016-08-02', '2016-08-03', '2016-08-04', '2016-08-05', '2016-08-06', '2016-09-07', '2016-09-08', '2016-09-09', '2016-09-10') DF <- data.frame(Speed, Dir, Date) DF$Date <- as.Date(DF$Date) DF$xend <- DF$Date + DF$Speed * 1 * cos((90 - DF$Dir) / 360 * 2 * pi) DF$yend <- DF$Speed * 1 * sin((90 - DF$Dir) / 360 * 2 * pi) # 绘图 ggplot(DF) + geom_segment(aes(x = Date, y = 0, xend = xend, yend = yend, col = factor(Date)), arrow = arrow(length = unit(0.5, "cm"))) + geom_point(aes(Date, 0), size = 1) + # 手动添加5 m/s参考箭头图例,位置可根据你的绘图范围调整 annotate("segment", x = as.Date("2016-09-01"), y = 25, xend = as.Date("2016-09-01") + 5, yend = 25, arrow = arrow(length = unit(0.3, "cm"))) + annotate("text", x = as.Date("2016-09-01") + 2.5, y = 26, label = "5 m/s", size = 3) + scale_x_date(labels = date_format('%b'), breaks = date_breaks('1 month')) + coord_fixed(1) + theme(legend.position = "none")
内容的提问来源于stack exchange,提问作者okscientist
相关产品推荐
相关产品推荐

