You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在R语言中实现特定位置风玫瑰图与地图叠加的方法问询

我来分享几个实用的方案,帮你把风玫瑰图完美叠加到地图上——不管是交互式的Leaflet还是静态的ggplot地图,都有可行的办法:

方案一:将ggplot风玫瑰图叠加到Leaflet交互式地图

Leaflet本身不直接支持ggplot对象,但可以把ggplot风玫瑰图转换成透明背景的图片,再作为 overlay 或自定义标记添加到地图上。这里需要用到webshot包来导出ggplot为图片,步骤如下:

  1. 先准备好你的风玫瑰图(用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))
  1. 将ggplot导出为临时透明png:
temp_img <- tempfile(fileext = ".png")
ggsave(temp_img, plot = wind_rose, width = 3, height = 3, bg = "transparent")
  1. 在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

火山引擎 最新活动