使用 R 语言绘图展示宗教活动场所分布

之前给大家分享过宗教活动场所基本信息数据和爬取课程:

×

×

在介绍数据的时候我绘制了一副地图展示宗教场所的分布:

为了方便大家使用这部分绘图代码,我把这部分代码单独拿出来讲解下。

下面案例中是选择了“宗教活动场所基本信息(含经纬度及其所处的省市区县)”数据的一般随机样本作为演示数据:“demo.xlsx”。

首先加载 tidyverse 和 sf 包:

library(tidyverse)
library(sf)
library(ggspatial)

读取 demo 数据:

readxl::read_xlsx("demo.xlsx") %>%
st_as_sf(coords = c("经度", "纬度"), crs = 4326, remove = F) %>%
mutate(type = paste0(宗教, " - ", 派别)) -> df
df
#> Simple feature collection with 21219 features and 18 fields
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: 78.86842 ymin: 18.32077 xmax: 134.0064 ymax: 51.25433
#> Geodetic CRS: WGS 84
#> # A tibble: 21,219 × 19
#> ID 经度 纬度 宗教 派别 场所名称 地址 负责…¹ 省_orign 市_or…² 县_or…³
#> * <dbl> <dbl> <dbl> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 15888 116. 23.0 佛教 汉语系 定光寺 广东… 释达仪 广东省 汕尾市 陆丰市
#> 2 15396 116. 24.3 佛教 汉语系 七圣宫 广东… 释宗辉 广东省 梅州市 梅县
#> 3 19971 115. 30.2 佛教 汉语系 汀祖镇… 湖北… 释透微 湖北省 鄂州市 鄂城区
#> 4 20895 114. 29.9 佛教 汉语系 明星寺 咸宁… 释能祺 湖北省 咸宁市 咸安区
#> 5 26845 118. 27.0 道教 正一 建瓯三… 福建… 龚源海 福建省 南平市 建瓯市
#> 6 14436 118. 24.4 佛教 汉语系 厦门妙… 福建… 则悟 福建省 厦门市 思明区
#> 7 7626 104. 33.2 佛教 汉语系 文县兴… 甘肃… 高碧莲 甘肃省 陇南市 文县
#> 8 6624 113. 35.1 佛教 汉语系 古观音寺 武陟… 温满圈 河南省 焦作市 武陟县
#> 9 23260 120. 27.9 道教 全真 湖岭镇… 浙江… 邱玉喜 浙江省 温州市 瑞安市
#> 10 1387 121. 28.1 佛教 汉语系 盐盆街… 浙江… 释智莲 浙江省 温州市 乐清市
#> # … with 21,209 more rows, 8 more variables: 省 <chr>, 省代码 <dbl>, 市 <chr>,
#> # 市代码 <dbl>, 县 <chr>, 县代码 <dbl>, geometry <POINT [°]>, type <chr>, and
#> # abbreviated variable names ¹负责人姓名, ²市_origin, ³县_origin

因为要绘制省级地图,所以省级行政区划数据、九段线数据和海岸线数据:

read_sf("2021行政区划/省.shp") -> prov
read_sf("九段线/九段线.shp") -> jdx
read_sf("海岸线/海岸线.shp") -> hax

theme_map.R 文件定义了 ggplot2 绘图主题,这里可能需要把 “Tiejili Regular.ttf” 字体文件替换着你自己电脑上的中文字体文件。

source("theme_map.R")

然后就可以开始绘制地图了。

首先绘制省界、九段线和海岸线:

ggplot(prov) +
geom_sf(fill = NA, linewidth = 0.2,
color = "gray") +
geom_sf(data = jdx, linewidth = 0.5,
color = "black", fill = NA) +
geom_sf(data = hax, linewidth = 0.3,
color = "#0055AA", fill = NA) -> p1
p1

然后添加宗教场所的散点:

p1 + geom_sf(data = df, aes(color = type), alpha = 0.5,
shape = 15, size = 1) -> p2
p2

这里使用颜色表示宗教场所的类型,由于默认的调色板不太好看,我们替换下:

p2 + scale_color_manual(values = c("#D7BA9F", "#800080", "#1C3181",  "#1BB6AF",  "#FFAD0A")) -> p3
p3

由于地理数据是 lonlat 坐标系的,所以绘制出来的中国地图是这样扁平的,使用 aea 坐标系绘制的更加好看:

p3 + coord_sf(crs = "+proj=aea +lat_0=0 +lon_0=105 +lat_1=25 +lat_2=47 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs",
xlim = c(-3500000, 3090000)) +
scale_x_continuous(expand = c(0.001, 0.001)) +
scale_y_continuous(expand = c(0.001, 0.001)) -> p4
p4

再设置下图例:

p4 + guides(color = guide_legend(nrow = 2)) -> p5
p5

添加指北针和比例尺:

p5 + annotation_scale(
width_hint = 0.2,
text_family = cnfont
) +
annotation_north_arrow(
location = "tr", which_north = "false",
width = unit(1.6, "cm"),
height = unit(2, "cm"),
style = north_arrow_fancy_orienteering(
text_family = cnfont
)
) -> p6
p6

设置下图表细节:

p6 +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank(),
panel.grid.major = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
plot.background = element_rect(color = "gray")) -> p7
p7

添加标题、副标题、caption 等:

p7 +
labs(title = "中国宗教活动场所地理分布",
subtitle = "绘制:微信公众号 RStata",
caption = "数据来源:国家宗教事务局\n<http://www.sara.gov.cn/zjhdcsjbxx/index.jhtml>",
color = "宗教")

最后,完整的代码是:

ggplot(prov) +
geom_sf(fill = NA, linewidth = 0.2,
color = "gray") +
geom_sf(data = jdx, linewidth = 0.5,
color = "black", fill = NA) +
geom_sf(data = hax, linewidth = 0.3,
color = "#0055AA", fill = NA) +
geom_sf(data = df, aes(color = type), alpha = 0.5,
shape = 15, size = 1) +
scale_color_manual(values = c("#D7BA9F", "#800080", "#1C3181", "#1BB6AF", "#FFAD0A")) +
coord_sf(crs = "+proj=aea +lat_0=0 +lon_0=105 +lat_1=25 +lat_2=47 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs",
xlim = c(-3500000, 3090000)) +
scale_x_continuous(expand = c(0.001, 0.001)) +
scale_y_continuous(expand = c(0.001, 0.001)) +
guides(color = guide_legend(nrow = 2)) +
annotation_scale(
width_hint = 0.2,
text_family = cnfont
) +
annotation_north_arrow(
location = "tr", which_north = "false",
width = unit(1.6, "cm"),
height = unit(2, "cm"),
style = north_arrow_fancy_orienteering(
text_family = cnfont
)
) +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank(),
panel.grid.major = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
plot.background = element_rect(color = "gray")) +
labs(title = "中国宗教活动场所地理分布",
subtitle = "绘制:微信公众号 RStata",
caption = "数据来源:国家宗教事务局\n<http://www.sara.gov.cn/zjhdcsjbxx/index.jhtml>",
color = "宗教") -> p

保存和裁边:

ggsave("中国宗教活动场所地理分布.png",
width = 9, height = 9, device = png)

knitr::plot_crop("中国宗教活动场所地理分布.png")
#> [1] "中国宗教活动场所地理分布.png"

点击这里跳转到 RStata 短书平台获取附件:使用 R 语言绘图展示宗教活动场所分布

评论