由於基礎圖表繪製系列推文還在加緊準備中,所以這期推文還是對一些感興趣的圖表進行繪製,這期涉及空間圖表繪製,主要涉及知識點如下:
ggplot2 + sf 中國標準地圖繪製本期的繪圖我們是按照如下圖表進行繪製的(該圖來自朋友公號):
其實我很早就想試著用R進行此類圖表的繪製了,但由於強大的Arcgis和繪圖進度等原因,導致遲遲沒有進行,這期就進行此類圖表的繪製。註:圖中散點的經緯度信息已從朋友那獲知,但涉及具體數據則是虛構的。
地圖讀取和散點標註這裡的中國地圖格式為 geojson 格式,還是使用sf包進行靈活讀取,具體代碼如下:
china_shp <- "中國省級地圖GS(2019)1719號.geojson"
nine <- "九段線GS(2019)1719號.geojson"
china <- sf::read_sf(china_shp)
nine_line <- sf::read_sf(nine)數據預覽如下(部分):
接下來我們進行探索性繪圖,主要使用geom_sf() 進行繪製,代碼如下:
library(ggspatial)
ggplot() +
geom_sf(data = china,fill="NA",size=1,color="black") +
geom_sf(data = nine_line) +
coord_sf(crs = "+proj=laea +lat_0=40 +lon_0=104")+
annotation_scale(location = "bl") +
# spatial-aware automagic north arrow
annotation_north_arrow(location = "tl", which_north = "false",
style = north_arrow_fancy_orienteering)這裡可以看到,我們沒有使用常規的WGS84坐標,而是採用 +proj=laea +lat_0=40 +lon_0=104 進行繪製,可視化結果如下:
比例尺和指北針的添加,則是依靠ggspatial包。
散點數據的讀取由於只獲得數據經緯度信息,其他數據均為虛構,數據預覽如下:
這裡注意點,要想使數據繪製在地圖上,我們需使用st_as_sf()對其進行轉換,處理:
scatter_df_tro <- st_as_sf(scatter_df,coords = c("lon", "lat"),crs = 4326)結果如下:注意紅色框中的內容
接下來將數據在地圖中顯示,具體代碼如下:
ggplot() +
geom_sf(data = china,fill="NA",size=.5,color="black") +
geom_sf(data = nine_line) +
geom_sf(data = scatter_df_tro,aes(fill=class,size=data),shape=21,colour='black',stroke=.25)+
coord_sf(crs = "+proj=laea +lat_0=40 +lon_0=104")+
scale_fill_manual(values = c("#E21C21","#3A7CB5","#51AE4F"))+
scale_size(range = c(1,5))+
annotation_scale(location = "bl") +
# spatial-aware automagic north arrow
annotation_north_arrow(location = "tl", which_north = "false",
style = north_arrow_fancy_orienteering)+
theme_linedraw()+
theme(text = element_text(family = 'Times_New_Roman',size = 12,face = "bold"),
panel.background = element_rect(fill = NA),
panel.grid.major = element_line(colour = "grey50"),
#axis.line = element_line(size = 1, colour = "black"),
panel.ontop = FALSE
)可視化結果如下:
這裡還存在如下問題:
(1) 儘量將南海部分放置在右下角(雖然這樣也可以)
(2) 圖例只是默認的,沒有進行定製化操作,影響美觀
cowplot包子圖添加cowplot包可是實現對繪圖結果的任意組合,很適合繪製地圖子圖的繪製,這裡直接給出繪圖代碼,如下:
library(cowplot)
map <- ggplot() +
geom_sf(data = china,fill=NA) +
geom_sf(data = nine_line,color='gray50',size=.8)+
geom_sf(data = scatter_df_tro,aes(fill=class,size=data),shape=21)+
coord_sf(ylim = c(-2387082,1654989),crs="+proj=laea +lat_0=40 +lon_0=104")+
scale_fill_manual(values = c("#E21C21","#3A7CB5","#51AE4F"))+
scale_size(range = c(1,5))+
annotation_scale(location = "bl",text_face = "bold",
text_family = "Times_New_Roman") +
# spatial-aware automagic north arrow
annotation_north_arrow(location = "tl", which_north = "false",
style = north_arrow_fancy_orienteering,
)+
#定製化圖例:這一步可以設計出亮眼的圖例哦
guides(fill = guide_legend(override.aes = list(size = 3),
title = "",
label.position = "right",
ncol=3,
),
size = guide_legend(
title = "",
label.position = "right",
ncol=5)) +
labs(
caption = 'Visualization by DataCharm')+
#theme_bw()+
theme(
text = element_text(family = 'Times_New_Roman',size = 18,face = "bold"),
panel.background = element_rect(fill = NA),
panel.grid.major = element_line(colour = "grey80",size=.2),
legend.key = element_rect(fill = "white"),
legend.position = "bottom",
)
nine_map <- ggplot() +
geom_sf(data = china,fill='NA') +
geom_sf(data = nine_line,color='gray70',size=1.)+
#geom_sf(data = scatter_df_tro,aes(fill=class,size=data),shape=21,colour='black',stroke=.25)+
coord_sf(ylim = c(-4028017,-1877844),xlim = c(117131.4,2115095),crs="+proj=laea +lat_0=40 +lon_0=104")+
theme(
#aspect.ratio = 1.25, #調節長寬比
axis.text = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank(),
panel.grid = element_blank(),
panel.background = element_blank(),
panel.border = element_rect(fill=NA,color="grey10",linetype=1,size=1.),
plot.margin=unit(c(0,0,0,0),"mm"))
gg_inset_map = ggdraw() +
draw_plot(map) +
draw_plot(nine_map, x = 0.8, y = 0.15, width = 0.1, height = 0.3)可視化效果如下:
這裡需注意的是xlim和ylim的設置,具體值都是在 +proj=laea +lat_0=40 +lon_0=104 投影坐標系下的值,而常規坐標轉不同坐標下的操作也很簡單,可使用st_transform進行操作。如下:
df2 <- tibble(lon = c(105,125),
lat = c(3,25),
)
df2 %>%
st_as_sf(coords = c("lon", "lat"), crs = 4326) -> df2_sf
df2_sf_pre <- sf::st_transform(df2_sf,crs="+proj=laea +lat_0=40 +lon_0=104")
df2_sf_pre即可獲取對應值,進而進行範圍設置。
總結該期推文也是基於自己對地圖的喜歡進行繪製,後面還是會以基礎圖表的繪製為主,希望大家能夠喜歡,多多支持。更多想法可以在 讀者討論 區進行留言告知。