【问题标题】:ggplot - Create a border overlay on top of mapggplot - 在地图顶部创建边框覆盖
【发布时间】:2018-03-26 17:24:08
【问题描述】:

因此,我正在尝试根据自定义变量创建带有边界的佛罗里达县级地图。我在这里添加了我正在尝试创建的旧版地图

从本质上讲,该地图显示了佛罗里达州县的区域细分,媒体市场用黑粗线边框勾勒出来。我能够很容易地绘制这些区域。我希望添加的是在媒体市场变量“MMarket”定义的区域之外的更粗的黑线边框,类似于上面显示的地图。填充变量将是 Region,媒体市场边界轮廓将使用 MMarket 定义。以下是数据的读取和强化方式:

#read in data
fl_data <- read_csv("Data for Mapping.csv")

#read in shapefiles
flcounties1 <- readOGR(dsn =".",layer = "Florida Counties")

#Fortify based on county name
counties.points <- fortify(flcounties1, region = "NAME")
counties.points$id <- toupper(counties.points$id)

#Merge plotting data and geospatial dataframe 
merged <- merge(counties.points, merged_data, by.x="id", by.y="County", all.x=TRUE)

fl_data 对象包含要映射的数据(包括媒体市场变量),并将 shapefile 数据读入flcounties1。这是我正在使用的合并数据框的示例:

 head(merged %>% select(id:group, Region, MMarket))
       id      long      lat order  hole piece     group    Region     MMarket
1 ALACHUA -82.65855 29.83014     1 FALSE     1 Alachua.1 Panhandle Gainesville
2 ALACHUA -82.65551 29.82969     2 FALSE     1 Alachua.1 Panhandle Gainesville
3 ALACHUA -82.65456 29.82905     3 FALSE     1 Alachua.1 Panhandle Gainesville
4 ALACHUA -82.65367 29.82694     4 FALSE     1 Alachua.1 Panhandle Gainesville
5 ALACHUA -82.65211 29.82563     5 FALSE     1 Alachua.1 Panhandle Gainesville
6 ALACHUA -82.64915 29.82648     6 FALSE     1 Alachua.1 Panhandle Gainesville

我可以使用以下代码轻松获得区域变量的地图:

ggplot() +
  # county polygons
  geom_polygon(data = merged, aes(fill = Region,
                                  x = long,
                                  y = lat,
                                  group = group)) +
  # county outline
  geom_path(data = merged, aes(x = long, y = lat, group = group), 
            color = "black", size = 1) +
  coord_equal() +
  # add the previously defined basic theme
  theme_map() +
  labs(x = NULL, y = NULL, 
       title = "Florida: Regions by County") +
  scale_fill_brewer(palette = "Set3",
                    direction = 1,
                    drop = FALSE,
                    guide = guide_legend(direction = "vertical",
                                         title.hjust = 0,
                                         title.vjust = 1,
                                         barheight = 30,
                                         label.position = "right",
                                         reverse = T,
                                         label.hjust = 0))

【问题讨论】:

  • 数据是否采用您开始时显示的格式,或者您是否对其进行了强化?如果它首先以 sf 或 sp 格式出现(即从形状文件或其他格式读取),我想我可以帮助使用不涉及强化的方法
  • 如果你不介意使用sfggplot2 的github 版本,有一个geom_sf 函数可以将地理形状添加为geom 层,你可以做得非常漂亮
  • @sebdalgarno 我编辑了主要帖子以显示如何读取数据。flcounties1 是 sp 格式,我最初使用县名作为 id 变量来加强这一点。当我将媒体市场变量添加到flcounties1 并使用该变量作为下面概述的@FelipeAlvarenga 进行强化时,地图仍然包含更大媒体市场中县的轮廓。我试图只保留创建媒体市场外部边界的县级轮廓,同时从包含它们的媒体市场中删除所有内部县级轮廓,就像在第一张地图中一样。
  • @Camille 你介意更详细地解释一下如何做到这一点吗?我愿意接受所有建议!
  • 不幸的是,很难提供没有可重复数据的解决方案。

标签: r ggplot2 maps choropleth


【解决方案1】:

如果您想使用ggplot2::geom_sf 进入sf,这是一个简单的示例。由于我没有你的 shapefile,我只是使用tigris 下载康涅狄格州的县分区 shapefile,然后将其转换为简单的要素对象。

更新说明:随着sf 的更新版本,一些事情似乎发生了变化,因此您现在应该只使用summarise 将城镇合并为县。

# download the shapefile I'll work with
library(dplyr)
library(ggplot2)
library(sf)

ct_sf <- tigris::county_subdivisions(state = "09", cb = T, class = "sf")

如果我想按原样绘制这些城镇,我可以使用ggplotgeom_sf

ggplot(ct_sf) +
  geom_sf(fill = "gray95", color = "gray50", size = 0.5) +
  # these 2 lines just clean up appearance
  theme_void() +
  coord_sf(ndiscr = F)

在没有任何功能的情况下分组和调用summarise 可为您提供多种功能的结合。我将根据县级 FIPS 代码(COUNTYFP 列)联合城镇。 sf 函数适合 dplyr 管道,太棒了。

所以这个:

ct_sf %>% 
    group_by(COUNTYFP) %>% 
    summarise()

会给我一个sf 对象,其中所有城镇都已合并到他们的县中。我可以将这两者结合起来,在第一层 geom_sf 中获得城镇地图,并在第二层中动态地对县进行联合:

ggplot(ct_sf) +
  geom_sf(fill = "gray95", color = "gray50", size = 0.5) +
  geom_sf(fill = "transparent", color = "gray20", size = 1, 
          data = . %>% group_by(COUNTYFP) %>% summarise()) +
  theme_void() +
  coord_sf(ndiscr = F)

没有更多fortify

【讨论】:

  • 你好,我想做和你一样的事情,虽然当我尝试时只有康涅狄格州的轮廓出现......在我的个人地图上也是如此。你有什么解释可以帮助我吗?谢谢
  • @thomasleon 从那时起,sftigris 中的某些内容似乎都发生了变化。感谢您的关注,我会尽快更新我的答案
【解决方案2】:

可能有更好的方法,但我的解决方法是在您需要绘制的所有维度中强化数据。

在你的情况下,我将创建你的县和 MMarkets 的强化数据集并像你一样绘制地图,但添加一层 geom_polygon 没有填充,所以只绘制边界。

merged_counties   <- fortify(merged, region = "id")
merged_MMarket    <- fortify(merged, region = "MMarket")

然后

ggplot() +
  # county polygons
  geom_polygon(data = merged_counties, aes(fill = Region,
                                  x = long,
                                  y = lat,
                                  group = group)) +
# here comes the difference
geom_polygon(data = merged_MMarket, aes(x = long,
                                  y = lat,
                                  group = group),
                                  fill = NA, size = 0.2) +
  # county outline
  geom_path(data = merged, aes(x = long, y = lat, group = group), 
            color = "black", size = 1) +
  coord_equal() +
  # add the previously defined basic theme
  theme_map() +
  labs(x = NULL, y = NULL, 
       title = "Florida: Regions by County") +
  scale_fill_brewer(palette = "Set3",
                    direction = 1,
                    drop = FALSE,
                    guide = guide_legend(direction = "vertical",
                                         title.hjust = 0,
                                         title.vjust = 1,
                                         barheight = 30,
                                         label.position = "right",
                                         reverse = T,
                                         label.hjust = 0))

使用巴西形状文件的示例

brasil      <- readOGR(dsn = "path to shape file", layer = "the file")
brasilUF    <- fortify(brasil, region = "ID_UF")
brasilRG    <- fortify(brasil, region = "REGIAO")

ggplot() +
  geom_polygon(data = brasilUF, aes(x = long, y = lat, group = group), fill = NA, color = 'black')  +
  geom_polygon(data = brasilRG, aes(x = long, y = lat, group = group), fill = NA, color = 'black', size = 2) +
  theme(rect            = element_blank(), # drop everything and keep only maps and legend
        line            = element_blank(),
        axis.text.x     = element_blank(),
        axis.text.y     = element_blank(),
        axis.title.x    = element_blank()
  ) +
  labs(x = NULL, y = NULL) +
  coord_map()

【讨论】:

  • 只是按照您的建议运行,并没有添加媒体市场区域边界,也没有真正改变地图。我希望添加的是在媒体市场变量“MMarket”定义的区域之外的更粗的黑线边框,类似于我帖子中包含的第一张地图中显示的内容。
  • 您的原始数据是SpatialPolygon 格式吗?因为它对我来说很好。我将在强化数据之前添加运行它的步骤。
  • 你能提供你提供的巴西例子中shape文件的路径和文件的层吗?我运行了您编辑的内容,但没有出现 MMarket 区域,只是每个县都有一个粗体轮廓。我认为这个问题可能是由于 MMarket 和区域变量在强化之前如何添加到“SpatialPolygon”数据框中。
  • 当然,只需按照上面的链接指向带有文件drive.google.com/drive/folders/…的示例
  • 我使用给定的 shapefile 尝试了您的示例,它按您所说的那样工作。不过,似乎仍然无法用我的数据重新创建它。您传递给fortify 的变量是否必须是某种类型?我目前正在传递一个因素。
猜你喜欢
  • 1970-01-01
  • 2017-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-21
  • 1970-01-01
相关资源
最近更新 更多