【问题标题】:ggplot map with l带有 l 的 ggplot 地图
【发布时间】:2026-01-05 13:40:01
【问题描述】:

我想使用 ggplot2 (v.9) 绘制一张世界地图,它结合了两条 if 信息。以下示例说明:

library(rgdal)
library(ggplot2)
library(maptools)

# Data from http://thematicmapping.org/downloads/world_borders.php.
# Direct link: http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip
# Unpack and put the files in a dir 'data'

gpclibPermit()
world.map <- readOGR(dsn="data", layer="TM_WORLD_BORDERS_SIMPL-0.3")
world.ggmap <- fortify(world.map, region = "NAME")

n <- length(unique(world.ggmap$id))
df <- data.frame(id = unique(world.ggmap$id),
                 growth = 4*runif(n),
                 category = factor(sample(1:5, n, replace=T)))

## noise
df[c(sample(1:100,40)),c("growth", "category")] <- NA


ggplot(df, aes(map_id = id)) +
     geom_map(aes(fill = growth, color = category), map =world.ggmap) +
     expand_limits(x = world.ggmap$long, y = world.ggmap$lat) +
     scale_fill_gradient(low = "red", high = "blue", guide = "colorbar")

但是,此解决方案不是同时显示 growthcategory 的好方法。 Growth 高度可见,但 category 几乎看不到,因为它只是一个边框。

我试图增加边框的大小,但没有运气(新的 geom_map 很难使用)。有谁知道如何在上面的例子中增加边框大小,或者更好,一种显示两个因素的机制?

一个额外的问题:国家名称,例如地图包(其中包含苏联!)使用的国家名称是示例中使用的数据是脆弱的。我更喜欢使用 ISO 3166-1 alpha-3(1)。有谁知道 ggplot2 可以轻松使用的数据,其中包含 ISO-...国家名称(包含在链接数据中)

结果:

result http://ompldr.org/vY3hsYQ

【问题讨论】:

  • world.map 是什么?它没有在您的代码中定义。如果我尝试 fortify(w,region="NAME"),我会收到“无效的多字节字符”错误。请提供可重现的代码。
  • 我在 fortify 行收到以下错误:“nchar(ID) 中的错误:无效的多字节字符串 1”
  • 我无法在 UTF8 系统上重现;我怀疑字体编码在这里是个问题。 iconv(.) 可以从一种编码系统转换为另一种编码系统。

标签: r ggplot2 geospatial


【解决方案1】:

我会为填充和线条颜色使用不同的色调范围:

ggplot(df, aes(map_id = id)) +
  geom_map(aes(fill = growth, color = category), map =world.ggmap) +
  expand_limits(x = world.ggmap$long, y = world.ggmap$lat) +
  scale_fill_gradient(high = "red", low = "white", guide = "colorbar") +
  scale_colour_hue(h = c(120, 240))

或者,对类别使用填充,对增长级别使用透明度。

ggplot(df, aes(map_id = id)) +
  geom_map(aes(alpha = growth, fill = category), map =world.ggmap) +
  expand_limits(x = world.ggmap$long, y = world.ggmap$lat) +
  scale_alpha(range = c(0.2, 1), na.value = 1)

这取决于你想展示什么。

以防万一,这里是改变线条大小的方法:

ggplot(df, aes(map_id = id)) +
 geom_map(aes(fill = growth, color = category, size = factor(1)), map =world.ggmap) +
 expand_limits(x = world.ggmap$long, y = world.ggmap$lat) +
 scale_fill_gradient(high = "red", low = "white", guide = "colorbar") +
 scale_colour_hue(h = c(120, 240)) + 
 scale_size_manual(values = 2, guide = FALSE)

这里是 HSV 版本:

df$hue <- ifelse(is.na(df$category), 0, as.numeric(df$category)/max(as.numeric(df$category), na.rm=T))
df$sat <- ifelse(is.na(df$growth), 0, df$growth/max(df$growth, na.rm=T))
df$fill <- ifelse(is.na(df$category), "grey50", hsv(df$hue, df$sat))

ggplot(df, aes(map_id = id)) +
 geom_map(aes(fill = fill), map =world.ggmap) +
 expand_limits(x = world.ggmap$long, y = world.ggmap$lat) +
 scale_fill_identity(guide = "none")

【讨论】:

  • 谢谢!问题是让线条“足够粗”以引起注意,即使图形打印得很小。
  • 我觉得你问的太多了。我认为不可能用一张小论文来展示这么多信息。
  • 你可以找到改变linesize的方法,但其实我觉得这没什么用...
  • alpha-proposal 非常好!谢谢。这让我想到,说明它的最佳方式可能是为每个类别设置一个基色,然后将饱和度确定为增长的函数。这或多或少是 alpha 所做的,特别是如果使用空白主题(或专门将 bg 设置为白色)。据您所知,是否有比您的 Alpha 方法更直接的方法来获得此结果?
  • 我认为色调和饱和度的组合很好。 ggplot2 的未来版本可能具有这样的功能,即色调、饱和度和值作为单独的 aes。无论如何,您可以通过手动设置来做到这一点。我会发布更新。
【解决方案2】:

一种选择是将增长映射到多边形质心处绘制的一些点的大小。

centroids <- as.data.frame(coordinates(world.map))
df <- data.frame(df,centroids)

choropleth <-ggplot() +
     geom_map(aes(fill = category, map_id = id),data = df, map =world.ggmap) +
     expand_limits(x = world.ggmap$long, y = world.ggmap$lat) + 
    scale_fill_hue(na.value=NA)
choropleth



choropleth + geom_point(aes(x=V1,y=V2,size=growth),data=df) +
    scale_area(range=c(0,3))

或者,如果您真的想将代码颜色加倍,则可以为点着色。请注意,您还可以使用新的 OpenStreetMap 包(无耻插件)添加卫星图像的栅格地图。

library(OpenStreetMap)
library(raster)
rastermap <- openmap(c(70,-179),
        c(-70,179),zoom=2,type='bing')
rastermap <- openproj(rastermap)
autoplot(rastermap,expand=FALSE) +
     geom_map(aes(x=70,y=70,fill = category, map_id = id),data = df,
        map =world.ggmap) +
     expand_limits(x = world.ggmap$long, y = world.ggmap$lat) + 
    scale_fill_hue(na.value=NA) + 
    geom_point(aes(x=V1,y=V2,colour=growth),data=df) +
    scale_colour_gradient(low = "red", high = "blue", 
        guide = "colorbar",na.value=NA)

【讨论】:

  • 伊恩,你的包裹看起来不错![1] 它确实增加了一个很好的触感。添加 alpha(ed)-fill 可能看起来很酷。顺便说一句:你知道 ggmap 包吗?根据摘要,它们听起来很相似。点子是个好主意。通过使用星星或看起来不太链接的东西,墨水臭味可以变成很好的东西。谢谢!
  • 我知道这个包。 OpenStreetMap 基本上是 RGoogleMaps 和 ggmap 的替代品。它可以做一些很酷的事情,比如切片缓存和地图投影转换。
  • @IanFellows 如果有兴趣,我只是在这里问了一个相关问题(使用相同的例子):*.com/questions/13219387/…
最近更新 更多