У меня есть данные мультигона, считанные из файла geojson.
geojson <- read_sf (filename)
Данные выглядят так:
Simple feature collection with 4 features and 1 field
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -16.64523 ymin: 27.23105 xmax: 39.81916 ymax: 65.99652
Geodetic CRS: WGS 84
# A tibble: 4 × 2
id geometry
<chr> <MULTIPOLYGON [°]>
1 Coverage (((-7.599085 33.35191, -7.813386 33.43519, -7.728468 33.51…
2 HighInterference (((30.60789 42.13764, 30.638 42.22092, 30.75046 42.22092, …
3 LowInterference (((24.75786 59.54255, 24.80001 59.62583, 24.96471 59.62583…
4 MediumInterference (((26.36263 58.87633, 26.40755 58.95961, 26.56905 58.95961…
Затем я использую geom_sf
, чтобы показать каждую строку данных своим цветом:
library ("ggplot2")
library ("sf")
library ("rnaturalearth")
library ("rnaturalearthdata")
library ("ggspatial")
library ("geojsonR")
europe <- ne_countries (scale = "medium", returnclass = "sf")
class (europe)
filename <- "geojson.geojson"
geojson <- read_sf (filename)
p <- ggplot () + geom_sf (data = europe)
p <- p + geom_sf (data = geojson[geojson$id == "Coverage", ], color = alpha ("green", 0.1), fill = alpha ("green", 0.1))
p <- p + geom_sf (data = geojson[geojson$id == "LowInterference", ], color = alpha ("yellow", 0.5), fill = alpha ("yellow", 0.5))
p <- p + geom_sf (data = geojson[geojson$id == "MediumInterference", ], color = alpha ("orange", 0.5), fill = alpha ("orange", 0.5))
p <- p + geom_sf (data = geojson[geojson$id == "HighInterference", ], color = alpha ("red", 0.5), fill = alpha ("red", 0.5))
p <- p + coord_sf (xlim = c(-20, 42), ylim = c(33, 72))
plot (p)
ggsave (paste (filename, ".pdf", sep = ""))
ggsave (paste (filename, ".png", sep = ""))
У меня такое ощущение, что это способ показать легенду. В файле не всегда присутствуют все слои. В показанном примере есть все, но какой-то один или несколько могут отсутствовать. Легенда всегда может иметь все возможные значения. У меня такое чувство, что это можно сделать, но я понятия не имею, как.
Вот пример геоджсона:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
0,
40
],
[
10,
50
],
[
0,
60
],
[
-10,
55
],
[
0,
40
]
]
]
]
},
"id": "Coverage"
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
20,
45
],
[
25,
50
],
[
20,
60
],
[
0,
50
],
[
20,
45
]
]
]
]
},
"id": "HighInterference"
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
10,
35
],
[
20,
35
],
[
20,
40
],
[
10,
40
],
[
10,
35
]
]
]
]
},
"id": "LowInterference"
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
30,
50
],
[
40,
50
],
[
40,
60
],
[
30,
60
],
[
30,
50
]
]
]
]
},
"id": "MediumInterference"
}
]
}
Редактировать: Теперь включен весь исходный код R. Теперь образец полностью воспроизводим с исходным кодом R и содержимым geojson.
@Friede Для Европы все просто europe <- ne_countries (scale = "medium", returnclass = "sf")
. Для geojson это большой файл. Я попытаюсь сделать короткий рабочий пример этого большого файла.
Ааа, вы имеете в виду {rnaturalearth}
. Это возвращает «мир», но я понимаю, откуда вы. :) Пожалуйста, сделайте это.
Да, сначала в функции ne_countries
у меня была выбрана только Европа, но затем в моем представлении отсутствовали Северная Африка и Ближний Восток, и это выглядело неправильно. :)
Вы можете установить заливку и цвет в aes
thetics и применить ручные шкалы заливки/цвета, например:
europe <- ne_countries (scale = "medium", returnclass = "sf",
continent = 'Europe' ## filter for Europe
)
geojson <- read_sf('geojson.geojson')
color_mapping <- c(
Coverage = alpha ("green", 0.1),
LowInterference = alpha ("yellow", 0.5),
MediumInterference = alpha ("orange", 0.5),
HighInterference = alpha ("red", 0.5)
)
## make the id column a factor, so legend entries are displayed
## even w/o any observation in this category (`drop = FALSE`)
geojson$id <-factor(geojson$id, levels = names(color_mapping))
ggplot() +
geom_sf(data = europe) +
geom_sf(data = geojson, aes(fill = id, color = id)) +
scale_fill_manual(values = color_mapping,
drop = FALSE, ## display legend entry even w/o observations
) +
scale_color_manual(values = color_mapping, drop = FALSE)
Примечание. scale_..._manual
также принимает аргумент na.value
, чтобы установить заливку/цвет для NA
.
Спасибо за Ваш ответ. Я попытался применить ваше решение к своему примеру, но мне это не удалось. Во-первых, я не знаю, как создавать полигоны с той же альфой, что и заливка. Во-вторых, я не знаю, как обрабатывать некоторые файлы, у которых нет некоторых категорий (например, отсутствует HighInterference).
Спасибо. Решение теперь работает. С легендой все еще есть небольшая проблема. Если какой-то тип многоугольника отсутствует, легенда также будет серой. Можно ли отобразить цвет в легенде, хотя данные для этого цвета отсутствуют?
Я нашел способ показать пропущенные значения в легенде. Отсутствующий идентификатор необходимо добавить без каких-либо данных, подобных этому geojson <- st_as_sf (geojson %>% complete (id), crs = st_crs (4326))
.
Не слишком уверен, что вы ищете. Просто aes(fill=id)
в ggplot2::geom_sf()
?
Код
library(sf)
library(ggplot2)
world <- rnaturalearth::ne_countries(scale = 110L, returnclass = "sf")
geojson <- st_as_sfc(str_geojson, GeoJSON = TRUE) |>
st_as_sf() |>
st_cast("POLYGON", group_or_split = TRUE, warn = FALSE)
geojson$id <- jsonlite::fromJSON(str_geojson)$features$id
box <- st_bbox(geojson)
ggplot() +
geom_sf(data = world) +
geom_sf(data = geojson, aes(fill = id, alpha = .2)) +
xlim(box[1L] - 10L, box[3L] + 10L) +
ylim(box[3L] - 10L, box[4L] + 10L) +
scale_alpha(guide = "none")
Выход
Примечание
str_geojson <- '{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
0,
40
],
[
10,
50
],
[
0,
60
],
[
-10,
55
],
[
0,
40
]
]
]
]
},
"id": "Coverage"
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
20,
45
],
[
25,
50
],
[
20,
60
],
[
0,
50
],
[
20,
45
]
]
]
]
},
"id": "HighInterference"
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
10,
35
],
[
20,
35
],
[
20,
40
],
[
10,
40
],
[
10,
35
]
]
]
]
},
"id": "LowInterference"
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
30,
50
],
[
40,
50
],
[
40,
60
],
[
30,
60
],
[
30,
50
]
]
]
]
},
"id": "MediumInterference"
}
]
}'
Пожалуйста, предоставьте образец ваших данных в воспроизводимом формате. Например. используйте
dput(head(geojson))
иdput(head(europe))
или аналогичные.