Cách tô bóng hình dạng
Có thể sử dụng ggrough(https://xvrdm.github.io/ggrough/index.html) để tô bóng các hình được tạo bởi geom_sf(ưu tiên) hoặc có thể geom_polygon? Xem câu hỏi này để biết câu hỏi trước cung cấp giao diện của cốt truyện mà tôi nghĩ đến và câu trả lời kèm theo của Z.Lin đã sửa đổi gói để làm cho nó tương thích với phiên bản hiện tại của ggplot2: Không thể sao chép cốt truyện ggplot2 này .
Đây là MWE của một bản đồ được tạo bằng cách sử dụng geom_sfmà tôi muốn tô bóng (từng hạt riêng lẻ) bằng cách sử dụng ggrough:
library(tidyverse)
library(magrittr)
library(ggplot2)
library(ggrough)
library(RColorBrewer)
library(tidycensus)
library(viridis)
#install.packages("devtools") # if you have not installed "devtools" package
#devtools::install_github("xvrdm/ggrough")
library(hrbrthemes)
#get nevada shapefile
counties <- get_acs(
geography = "county", year = 2018, geometry = TRUE,
variables = "B19013_001", keep_geo_vars=TRUE
) %>% filter(STATEFP=="32")
counties$GEOID <- as.integer(counties$GEOID)
#############
a <- ggplot() +
geom_sf(data = counties, aes(fill = estimate)) +
scale_fill_viridis(discrete=FALSE, name="", guide=FALSE) +
theme_bw() +
theme(legend.position = c(0.15, .15)) +
theme(plot.subtitle = element_text(hjust = 0.8, vjust=-10, size=30)) +
theme(panel.background = element_rect(fill = 'white')) +
theme(panel.grid = element_blank(),axis.title = element_blank(),
axis.text = element_blank(),axis.ticks = element_blank(),
panel.border = element_blank())+
theme(legend.position = c(0.25, .15), legend.key.size = unit(2,"line"),
legend.title=element_text(size=16),
legend.text=element_text(size=14),
legend.direction = "vertical",
legend.box = "horizontal") +
labs(caption = "")
a
Điều này tạo ra những điều sau:
Làm cách nào tôi có thể tô bóng các quận của bản đồ này bằng cách sử dụng ggroughhoặc điều này là không thể? Lưu ý rằng tôi nghĩ rằng điều đó ggroughcó thể xử lý geom_col, geom_bar, geom_tile, geom_geom_area, geom_ribbon, geom_violin, geom_point, geom_jitter, geom_dotplot, geom_line, and geom_smooth, nhưng tôi không chắc chắn về geom_sfhoặc geom_polygon; nếu không, có dễ dàng thêm chúng vào không?
*** Cập nhật Đây là một ví dụ khác, được lấy từ https://ggplot2.tidyverse.org/reference/ggsf.html:
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
b <- ggplot(nc) +
geom_sf(aes(fill = AREA))
b
Điều này tạo ra:
*** Kết thúc cập nhật
(Đây là một ví dụ, được tạo với ggrough, về cách tôi muốn bóng của các quận trông như thế nào
Đây là một nỗ lực không thành công (một lần nữa dựa vào mã từ câu trả lời của Z.Lin ở đây: Không thể sao chép âm mưu ggplot2 này ):
parse_polygons <- function (svg) {
shape <- "polygon" # was "polyline" in ggrough:::parse_areas
keys <- NULL
ggrough:::parse_shape(svg, shape, keys) %>% {
purrr::map(.,
~purrr::list_modify(.x,
points = stringr::str_squish(.x$points) %>%
{stringr::str_glue("M{.}Z")},
shape = "path"))
}
}
trace(ggrough:::parse_rough, edit = TRUE)
# paste the following function into the pop-up window
function (svg, geom) {
rough_els <- list()
if (geom %in% c("GeomCol", "GeomBar", "GeomTile", "Background")) {
rough_els <- append(rough_els, parse_rects(svg))
}
if (geom %in% c("GeomSmooth", "Background")) { # removed GeomArea / GeomViolin from here
rough_els <- append(rough_els, parse_areas(svg))
}
if (geom %in% c("GeomArea", "GeomRibbon", "GeomViolin")) { # new condition here
rough_els <- append(rough_els, parse_polygons(svg))
}
if (geom %in% c("GeomPoint", "GeomJitter", "GeomDotPlot", "Background")) {
rough_els <- append(rough_els, parse_circles(svg))
}
if (geom %in% c("GeomLine", "GeomSmooth", "Background")) {
rough_els <- append(rough_els, parse_lines(svg))
}
if (geom %in% c("Background")) {
rough_els <- append(rough_els, parse_texts(svg))
}
purrr::map(rough_els, ~purrr::list_modify(.x, geom = geom))
}
options <- list(GeomSf=list(fill_style="hachure",
angle_noise=0.5,
gap_noise=0.2,
gap=1.5,
fill_weight=1))
get_rough_chart(a, options)
Điều này tạo ra thông báo lỗi:
Error in `*tmp*`[[i]] : subscript out of bounds
*** Cập nhật
Hoặc với ví dụ thứ hai:
options <- list(GeomSf=list(fill_style="hachure",
angle_noise=0.5,
gap_noise=0.2,
gap=1.5,
fill_weight=1))
get_rough_chart(b, options)
Cùng một lỗi.
*** Kết thúc cập nhật.
Cũng lưu ý rằng có thể tạo bản đồ bằng cách sử dụng geom_polygon, vì vậy điều đó cũng được quan tâm, mặc dù geom_sfđược ưu tiên hơn.
Trả lời
library(magrittr)
library(ggplot2)
library(ggrough)
Thay thế parse_roughbằng cách sử dụngtrace
trace(ggrough:::parse_rough, edit=TRUE)
Trong cửa sổ bật lên, dán cái này để parse_roughsử dụng parse_sfcho GeomSf.
function (svg, geom)
{
rough_els <- list()
if (geom %in% c("GeomCol", "GeomBar", "GeomTile",
"Background")) {
rough_els <- append(rough_els, parse_rects(svg))
}
if (geom %in% c("GeomArea", "GeomViolin", "GeomSmooth",
"Background")) {
rough_els <- append(rough_els, parse_areas(svg))
}
if (geom %in% c("GeomPoint", "GeomJitter", "GeomDotPlot",
"Background")) {
rough_els <- append(rough_els, parse_circles(svg))
}
if (geom %in% c("GeomLine", "GeomSmooth", "Background")) {
rough_els <- append(rough_els, parse_lines(svg))
}
if (geom %in% c("Background")) {
rough_els <- append(rough_els, parse_texts(svg))
}
if (geom %in% c("GeomSf")) {
rough_els <- append(rough_els, parse_sf(svg))
}
purrr::map(rough_els, ~purrr::list_modify(.x, geom = geom))
}
Tạo chức năng parse_sf.
parse_sf <- function (svg) {
shape <- "path"
keys <- NULL
ggrough:::parse_shape(svg, shape, keys) %>% {
purrr::map(.,
~purrr::list_modify(.x,
points = .x$d,
shape = "path"
))
}
}
Tạo cốt truyện mong muốn
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
b <- ggplot(nc) +
geom_sf(aes(fill = AREA))
b
options <- list(GeomSf=list(fill_style="hachure",
angle_noise=0.5,
gap_noise=0.2,
gap=1.5,
fill_weight=1))
get_rough_chart(b, options)