在R语言中实现特定位置风玫瑰图与地图叠加的方法问询
我来分享几个实用的方案,帮你把风玫瑰图完美叠加到地图上——不管是交互式的Leaflet还是静态的ggplot地图,都有可行的办法:
方案一:将ggplot风玫瑰图叠加到Leaflet交互式地图
Leaflet本身不直接支持ggplot对象,但可以把ggplot风玫瑰图转换成透明背景的图片,再作为 overlay 或自定义标记添加到地图上。这里需要用到webshot包来导出ggplot为图片,步骤如下:
- 先准备好你的风玫瑰图(用openair或自定义ggplot都可以):
library(leaflet) library(ggplot2) library(openair) library(webshot) # 先安装依赖的phantomjs webshot::install_phantomjs() # 用openair示例数据生成ggplot风格的风玫瑰,去掉冗余背景 data(mydata) wind_rose <- windRose(mydata, ws = "ws", wd = "wd", type = "ggplot") + theme_void() + theme(plot.background = element_rect(fill = "transparent", color = NA))
- 将ggplot导出为临时透明png:
temp_img <- tempfile(fileext = ".png") ggsave(temp_img, plot = wind_rose, width = 3, height = 3, bg = "transparent")
- 在Leaflet中添加图片:
你可以选择用addImageOverlay把风玫瑰作为区域叠加,或者用addMarkers精准定位到某个经纬度:
# 目标位置(示例为伦敦附近经纬度) target_lat <- 51.5 target_lng <- -0.1 # 方式1:作为区域叠加 leaflet() %>% addTiles() # 用默认OpenStreetMap瓦片,无需API addImageOverlay( url = temp_img, bounds = list( c(target_lat - 0.05, target_lng - 0.05), c(target_lat + 0.05, target_lng + 0.05) ), opacity = 0.8 ) # 方式2:作为精准标记 rose_icon <- makeIcon( iconUrl = temp_img, iconWidth = 120, iconHeight = 120, iconAnchorX = 60, iconAnchorY = 60 # 锚点设为图片中心 ) leaflet() %>% addTiles() %>% addMarkers(lng = target_lng, lat = target_lat, icon = rose_icon)
方案二:无需Google API的静态地图叠加(ggmap/ggspatial)
如果你不需要交互式地图,用静态ggplot叠加会更简单,而且可以避开Google API的限制,用免费的Stamen或OpenStreetMap瓦片:
用ggmap调用Stamen地图
ggmap支持直接调用Stamen的免费地图服务,不需要API密钥:
library(ggmap) library(ggplot2) library(openair) # 获取目标区域的Stamen浅色地图 map_bbox <- c(left = -0.2, bottom = 51.4, right = 0, top = 51.6) base_map <- get_stamenmap( bbox = map_bbox, zoom = 12, maptype = "toner-lite" # 浅色风格更适合叠加风玫瑰 ) # 生成透明背景的风玫瑰图 wind_rose <- windRose(mydata, ws = "ws", wd = "wd", type = "ggplot") + theme( plot.background = element_rect(fill = "transparent", color = NA), panel.background = element_rect(fill = "transparent", color = NA) ) + coord_fixed() # 叠加地图和风玫瑰 ggmap(base_map) + annotation_custom( grob = ggplotGrob(wind_rose), xmin = -0.15, xmax = -0.05, # 风玫瑰在地图上的经度范围 ymin = 51.45, ymax = 51.55 # 风玫瑰在地图上的纬度范围 )
用ggspatial实现更灵活的空间叠加
ggspatial是专门为ggplot设计的空间可视化包,支持多种免费地图瓦片,用法更原生:
library(ggspatial) library(ggplot2) library(openair) # 创建基础地图 base_map <- ggplot() + annotation_map_tile( type = "stamen_toner_lite", cachedir = system.file("rosm.cache", package = "ggspatial") ) + coord_sf(xlim = c(-0.2, 0), ylim = c(51.4, 51.6)) # 叠加风玫瑰 base_map + annotation_custom( grob = ggplotGrob(wind_rose), xmin = -0.15, xmax = -0.05, ymin = 51.45, ymax = 51.55 )
小技巧:自定义风玫瑰图样式
如果觉得openair的默认样式不够美观,可以自己用ggplot写风玫瑰,更灵活控制细节:
# 预处理风向数据,分成8个区间 mydata$wd_bin <- cut(mydata$wd, breaks = seq(0, 360, 45), include.lowest = TRUE) # 计算每个风向区间的平均风速 wind_stats <- aggregate(ws ~ wd_bin, data = mydata, mean) # 自定义风玫瑰 custom_wind_rose <- ggplot(wind_stats, aes(x = wd_bin, y = ws)) + geom_bar(stat = "identity", fill = "coral", alpha = 0.7) + coord_polar(start = -pi/8) # 调整起始角度对应正北方向 theme_void() + theme(plot.background = element_rect(fill = "transparent", color = NA))
内容的提问来源于stack exchange,提问作者ajilesh




