You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在亚洲Shapefile地图的各国质心处添加分组柱状图?

解决方案:在亚洲地图质心添加分组柱状图

核心思路

要在地图质心位置添加分组柱状图,我们需要将每个国家的小型柱状图转换为图形对象(grob),再通过annotation_custom将其定位到对应质心坐标上,同时处理数据标准化和位置偏移避免重叠。

步骤1:数据预处理与标准化

先修正数据处理逻辑,同时对人口、GDP指标做标准化(两者数值量级差距极大,不标准化会导致小图显示异常):

library(sf)
library(tidyverse)
library(reshape2)
library(grid)

# 读取地图数据
map <- read_sf(dsn = "C:/Users/Adrian/Desktop/PhD/Data/ne_50m_admin_0_countries", 
               layer = "ne_50m_admin_0_countries")

# 筛选亚洲国家并计算质心
asia <- map %>% 
  filter(CONTINENT == "Asia") %>% 
  mutate(centroids = st_centroid(st_geometry(.)),
         long = st_coordinates(centroids)[,1],
         lat = st_coordinates(centroids)[,2])

# 整理指标数据并做0-1标准化
data <- asia %>% 
  as.data.frame() %>% 
  select(GU_A3, POP_EST, GDP_MD) %>% 
  mutate(across(c(POP_EST, GDP_MD), ~ scales::rescale(.x, to = c(0, 1)))) %>% 
  melt(id.vars = "GU_A3")

步骤2:创建生成小柱状图的函数

编写函数生成单国的小型柱状图,并简化主题(去掉冗余元素,缩小尺寸):

# 生成单国小柱状图的函数
make_bar_grob <- function(country_code) {
  p <- data %>% 
    filter(GU_A3 == country_code) %>% 
    ggplot(aes(x = variable, y = value, fill = variable)) +
    geom_bar(stat = "identity", position = "dodge", width = 0.8) +
    ggtitle(country_code) +
    theme_minimal() +
    theme(
      plot.title = element_text(size = 8, hjust = 0.5),
      axis.text = element_blank(),
      axis.title = element_blank(),
      legend.position = "none",
      plot.margin = margin(1, 1, 1, 1, "pt"),
      panel.grid = element_blank()
    )
  ggplotGrob(p)
}

步骤3:绘制地图并添加所有小柱状图

在地图基础上循环添加每个国家的柱状图,同时调整位置避免与地图重叠:

# 初始化地图对象
map_plot <- ggplot(data = asia) +
  geom_sf(fill = "#f0f0f0", color = "white") +
  coord_sf(xlim = c(25, 180), ylim = c(-10, 75)) + # 限定亚洲显示范围
  theme_minimal()

# 循环添加每个国家的柱状图grob
for (i in 1:nrow(asia)) {
  country_code <- asia$GU_A3[i]
  grob <- make_bar_grob(country_code)
  # 将柱状图放在质心上方,可根据实际调整偏移量
  map_plot <- map_plot +
    annotation_custom(
      grob = grob,
      xmin = asia$long[i] - 2, xmax = asia$long[i] + 2,
      ymin = asia$lat[i] + 1, ymax = asia$lat[i] + 4
    )
}

# 添加国家标签(放在柱状图下方)
map_plot <- map_plot +
  geom_text(
    data = asia,
    aes(x = long, y = lat, label = GU_A3),
    size = 3, color = "darkblue", vjust = 1.5
  )

# 显示最终地图
print(map_plot)

关键优化点

  • 数据标准化:用scales::rescale将指标缩放到0-1区间,解决不同指标量级差距过大导致的显示问题。
  • 位置调整:通过xmin/xmax和ymin/ymax控制柱状图的位置与大小,若仍有重叠可针对特定国家手动修改偏移量。
  • 主题简化:去掉小柱状图的坐标轴、图例等冗余元素,避免占用过多地图空间。

内容的提问来源于stack exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:05:44