r - 如何将条形图绘制到 ggplot2 map 上

标签 r ggplot2 gridextra r-grid

我找到了类似问题的答案,但其中大多数都使用包 rworldmap , ggmap , ggsubplotgeom_subplot2d 。例如,参见herehere

我想知道如何将其他 ggplot 对象(例如条形图)绘制到从 shapefile 创建的 map 上。我用的可以下载here .

编辑

正如 @beetroot 正确指出的那样,可以在上面发布的链接下下载的新文件已经发生了显着变化。因此,shapefile等的名称进行了调整。

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

map.det<- readOGR(dsn="<path to your directory>/swissBOUNDARIES3D100216/swissBOUNDARIES3D/V200/SHAPEFILE_LV03", layer="VECTOR200_KANTONSGEBIET")
map.kt <- map.det[map.det@data$KANTONSNUM=="CH01000000"|map.det@data$KANTONSNUM=="CH19000000",]


#get centroids
map.test.centroids <- gCentroid(map.kt, byid=T)
map.test.centroids <- as.data.frame(map.test.centroids)
map.test.centroids$KANTONSNR <- row.names(map.test.centroids)

#create df for ggplot
kt_geom <- fortify(map.kt, region="KANTONSNUM")

#Plot map
map.test <- ggplot(NULL)+
        geom_polygon(data=kt_geom, aes(long, lat, group=group), fill="white")+
        coord_fixed()+
        geom_path(data=kt_geom, color="gray48", mapping=aes(long, lat, group=group), size=0.2)+
        geom_point(data=map.test.centroids, aes(x=x, y=y), size=9, alpha=6/10)

mapp

这会产生这样的 map 。到目前为止,一切都很好。 enter image description here

但是,我在组合两个图时遇到困难,例如 map map.test例如,这个:

geo_data <- data.frame(who=rep(c(1:2), each=2),
                   value=as.numeric(sample(1:100, 4, replace=T)),
                   KANTONSNR=rep(c(1,19), 2))

bar.testplot <- ggplot()+
     geom_bar(data=geo_data, aes(factor(id),value,group=who),position='dodge',stat='identity')

条形图应位于两个多边形的中心,即两个点所在的位置。我可以生成条形图并将它们分别绘制到 map 上,如果这样会让事情变得更容易的话。

最佳答案

我修改了一些代码以使示例更具说明性。我不仅绘制了 2 个坎顿,而且绘制了 47 个坎顿。

library(rgdal)
library(ggplot2)
library(rgeos)
library(maptools)
library(grid)
library(gridExtra)

map.det<- readOGR(dsn="c:/swissBOUNDARIES3D/V200/SHAPEFILE_LV03", layer="VECTOR200_KANTONSGEBIET")
map.kt <- map.det[map.det$ICC=="CH" & (map.det$OBJECTID %in% c(1:73)),]

# Merge polygons by ID
map.test <- unionSpatialPolygons(map.kt, map.kt@data$OBJECTID)

#get centroids
map.test.centroids <- gCentroid(map.test, byid=T)
map.test.centroids <- as.data.frame(map.test.centroids)
map.test.centroids$OBJECTID <- row.names(map.test.centroids)

#create df for ggplot
kt_geom <- fortify(map.kt, region="OBJECTID")

#Plot map
map.test <- ggplot(kt_geom)+
  geom_polygon(aes(long, lat, group=group), fill="white")+
  coord_fixed()+
  geom_path(color="gray48", mapping=aes(long, lat, group=group), size=0.2)+
  geom_point(data=map.test.centroids, aes(x=x, y=y), size=2, alpha=6/10)

map.test

initial plot

让我们生成条形图数据。

set.seed(1)
geo_data <- data.frame(who=rep(c(1:length(map.kt$OBJECTID)), each=2),
                       value=as.numeric(sample(1:100, length(map.kt$OBJECTID)*2, replace=T)),
                       id=rep(c(1:length(map.kt$OBJECTID)), 2))

现在制作 47 个条形图,稍后应在中心点绘制。

bar.testplot_list <- 
  lapply(1:length(map.kt$OBJECTID), function(i) { 
    gt_plot <- ggplotGrob(
      ggplot(geo_data[geo_data$id == i,])+
        geom_bar(aes(factor(id),value,group=who), fill = rainbow(length(map.kt$OBJECTID))[i],
                 position='dodge',stat='identity', color = "black") +
        labs(x = NULL, y = NULL) + 
        theme(legend.position = "none", rect = element_blank(),
              line = element_blank(), text = element_blank()) 
    )
    panel_coords <- gt_plot$layout[gt_plot$layout$name == "panel",]
    gt_plot[panel_coords$t:panel_coords$b, panel_coords$l:panel_coords$r]
    })

在这里,我们将ggplot转换为gtable,然后将它们裁剪为仅包含每个条形图的面板。您可以修改此代码以保留比例、添加图例、标题等。

我们可以借助 annotation_custom 将此条形图添加到初始 map 中。

bar_annotation_list <- lapply(1:length(map.kt$OBJECTID), function(i) 
  annotation_custom(bar.testplot_list[[i]], 
                    xmin = map.test.centroids$x[map.test.centroids$OBJECTID == as.character(map.kt$OBJECTID[i])] - 5e3,
                    xmax = map.test.centroids$x[map.test.centroids$OBJECTID == as.character(map.kt$OBJECTID[i])] + 5e3,
                    ymin = map.test.centroids$y[map.test.centroids$OBJECTID == as.character(map.kt$OBJECTID[i])] - 5e3,
                    ymax = map.test.centroids$y[map.test.centroids$OBJECTID == as.character(map.kt$OBJECTID[i])] + 5e3) )

result_plot <- Reduce(`+`, bar_annotation_list, map.test)

enter image description here

关于r - 如何将条形图绘制到 ggplot2 map 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36063043/

相关文章:

r - 尝试从大 mcmc.list 中提取时内存耗尽

r - dplyr 过滤器语句不在 data.frame 的表达式中

r - 在 Debian 8.2 上安装 R

r - ggplot 保留组合图的重复颜色

r - 将 tableGrob 与 ggplot2 y 轴并列

r - 如何降低 gridExtra 的 grid.arrange 中的主标题?

R:ggplot背景渐变着色

python - Plotnine:如何在绘制图形时删除 ggplot:(xxx) 类型烦人的文本输出

r - 使用 ggplot2 组合 Boxplot 和 Histogram

R ggplot 热图使用 geom_tile() : how to sort by year and show all years in y-axis?