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

ggplot2绘制世界地图:连接数据框时如何保留原数据行数?

解决世界地图可视化时数据行数膨胀的问题

首先得帮你理清问题根源:你用left_join(df, world, by = c("Country"="region"))后行数暴增,是因为ggplot2::map_data('world')里的每个国家对应成百上千个经纬度点——这些点是用来绘制国家轮廓的。关联时,原数据框df里的每一行都会和对应国家的所有轮廓点匹配,自然就出现了1400万条观测值。

下面给你两种适配不同需求的最佳方案:

方案1:聚合数据后制作填充式世界地图(最常用场景)

如果你的目标是做填充地图(比如按国家着色展示自杀率指标),正确思路是先对原数据做聚合,得到每个分组(比如国家+年份)的汇总值,再和地图数据关联。这样关联后的行数是地图轮廓点的数量,不会出现爆炸。

示例代码:

library(dplyr)
library(ggplot2)

# 按国家+年份聚合,计算平均每10万人口自杀率(可根据需求替换聚合逻辑)
df_agg <- df %>%
  group_by(Country, Year) %>%
  summarise(avg_suicides_per_100k = mean(Suicides_per_100k, na.rm = TRUE),
            .groups = "drop")

# 关联地图数据(把地图数据放前面,保证轮廓点完整)
world <- map_data('world')
world_joined <- left_join(world, df_agg, by = c("region" = "Country"))

# 绘制填充地图
ggplot(world_joined, aes(x = long, y = lat, group = group, fill = avg_suicides_per_100k)) +
  geom_polygon(color = "white", linewidth = 0.2) +
  scale_fill_viridis_c(option = "plasma", na.value = "gray90") +
  facet_wrap(~Year) + # 可选:按年份分面展示
  theme_minimal() +
  theme(axis.text = element_blank(), axis.title = element_blank())

方案2:获取国家中心点,保留原数据行数

如果你确实需要保留原df的每一行(比如要在地图上标注每个细分组的信息),那应该用国家中心点坐标而非完整轮廓点。每个国家只对应一行坐标数据,关联后行数就和原df完全一致了。

示例代码:

library(dplyr)
library(ggplot2)

# 从地图数据中提取每个国家的中心点坐标
country_centers <- map_data('world') %>%
  group_by(region) %>%
  summarise(center_long = mean(long, na.rm = TRUE),
            center_lat = mean(lat, na.rm = TRUE),
            .groups = "drop")

# 关联原数据,行数和原df完全一致
df_with_centers <- left_join(df, country_centers, by = c("Country" = "region"))

# 绘制底图+散点标注
ggplot() +
  # 先画世界地图底图
  geom_polygon(data = map_data('world'), 
               aes(x = long, y = lat, group = group), 
               fill = "lightgray", color = "white", linewidth = 0.2) +
  # 叠加原数据的点(用颜色/大小表示指标)
  geom_point(data = df_with_centers, 
             aes(x = center_long, y = center_lat, 
                 color = Suicides_per_100k, size = Population),
             alpha = 0.7) +
  scale_color_viridis_c(option = "plasma") +
  theme_minimal() +
  theme(axis.text = element_blank(), axis.title = element_blank())

补充提示

如果遇到部分国家匹配失败(比如原数据国名和map_data里的region字段名称不一致),可以手动整理一份国名映射表统一命名,比如把"USA"改成"United States"。

内容的提问来源于stack exchange,提问作者Matheus Barreto Alves

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 17:07:53