英文:
Adding a legend to a ggplot map
问题
我正在使用ggplot2来可视化与地图相关的数据。我已根据连续值对区域进行了着色,并希望添加一个带有颜色和区域名称的图例。我的数据有点复杂,不太方便共享,但我已经使用公共数据(ggplot2中的地图绘制)重新创建了这种情况。以下代码创建了包含的地图:
library(ggplot2)
library(sf)
# 导入一个geojson或shapefile
map <- read_sf("https://raw.githubusercontent.com/R-CoderDotCom/data/main/shapefile_spain/spain.geojson")
ggplot(map) +
geom_sf(color = "white", aes(fill = unemp_rate)) +
geom_sf_text(aes(label = name), size = 2)
代替连续默认图例,我想要一个具有名称、数字和颜色的图例。基本上,一个图例显示数据的name
和unemp_rate
列,颜色与地图匹配(例如unemp_rate
)。有点类似于第二张包含的图片的图例(但颜色不正确)。
name | unemp_rate |
---|---|
"Andalucía" | 18.68 |
"Aragón" | 8.96 |
"Principado de Asturias" | 11.36 |
"Islas Baleares" | 9.29 |
"Islas Canarias" | 17.76 |
"Cantabria" | 8.17 |
"Castilla y León" | 10.19 |
"Castilla-La Mancha" | 14.11 |
"Cataluña" | 9.29 |
"Comunidad Valenciana" | 12.81 |
"Extremadura" | 16.73 |
"Galicia" | 11.20 |
"Comunidad de Madrid" | 10.18 |
"Región de Murcia" | 12.18 |
"Comunidad Foral de Navarra" | 8.76 |
"País Vasco" | 8.75 |
"La Rioja" | 10.19 |
"Ceuta y Melilla" | 23.71 |
实际代码如下:
ggplot(map, aes(geometry = geometry, fill = Y1)) +
theme_bw() + geom_sf(show.legend = FALSE) +
scale_fill_gradient2(low = "brown", high = "green") +
theme(
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank())
英文:
I am using ggplot2 to visualise map-related data. I have coloured regions according to a continuous value, and I would like to add a legend with colors and region names. My own data is a bit cumbersome to share, but I have recreated the scenario with public data (Mapping in ggplot2). The following code creates the included map:
library(ggplot2)
library(sf)
# Import a geojson or shapefile
map <- read_sf("https://raw.githubusercontent.com/R-CoderDotCom/data/main/shapefile_spain/spain.geojson")
ggplot(map) +
geom_sf(color = "white", aes(fill = unemp_rate)) +
geom_sf_text(aes(label = name), size = 2)
Instead of the continuous default legend, I would like to have a legend with names, numbers and colors. Basically, a legend that shows the name
and unemp_rate
columns of the data with colors matching the map (eg. unemp_rate
). Somewhat like the legend of the second included picture (but the colors are not right).
name | unemp_rate |
---|---|
"Andalucía" | 18.68 |
"Aragón" | 8.96 |
"Principado de Asturias" | 11.36 |
"Islas Baleares" | 9.29 |
"Islas Canarias" | 17.76 |
"Cantabria" | 8.17 |
"Castilla y León" | 10.19 |
"Castilla-La Mancha" | 14.11 |
"Cataluña" | 9.29 |
"Comunidad Valenciana" | 12.81 |
"Extremadura" | 16.73 |
"Galicia" | 11.20 |
"Comunidad de Madrid" | 10.18 |
"Región de Murcia" | 12.18 |
"Comunidad Foral de Navarra" | 8.76 |
"País Vasco" | 8.75 |
"La Rioja" | 10.19 |
"Ceuta y Melilla" | 23.71 |
My actual code looks like so:
ggplot(map, aes(geometry = geometry, fill = Y1)) +
theme_bw() + geom_sf(show.legend = FALSE) +
scale_fill_gradient2(low = "brown", high = "green") +
theme(
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank())
答案1
得分: 2
也许可以考虑使用嵌套的条形图代替:
library(ggplot2)
library(sf)
library(dplyr)
library(patchwork)
# 导入一个geojson或shapefile
map_ <- read_sf("https://raw.githubusercontent.com/R-CoderDotCom/data/main/shapefile_spain/spain.geojson") %>%
mutate(name = forcats::fct_reorder(name, desc(unemp_rate)))
g1 <- map_ %>%
ggplot() +
geom_sf(color = "white", aes(fill = unemp_rate)) +
geom_sf_text(aes(label = name), size = 2) +
scale_fill_gradient2(low = "brown", high = "green", midpoint = 16) +
theme_minimal() +
theme(legend.position = "none", axis.text = element_blank(), axis.title = element_blank(), panel.grid = element_blank())
g2 <- map_ %>%
ggplot(aes(x = unemp_rate, y = name, fill = unemp_rate)) +
geom_col() +
scale_fill_gradient2(low = "brown", high = "green", midpoint = 16) +
geom_text(aes(label = name, x = .5, hjust = 0)) +
geom_text(aes(label = unemp_rate), nudge_x = - .5, hjust = 1) +
theme_void() +
theme(legend.position = "none")
g1 + inset_element(g2, 0, .2, .9, 1)
<details>
<summary>英文:</summary>
Perhaps an inset bar chart instead:
library(ggplot2)
library(sf)
library(dplyr)
library(patchwork)
Import a geojson or shapefile
map_ <- read_sf("https://raw.githubusercontent.com/R-CoderDotCom/data/main/shapefile_spain/spain.geojson") %>%
mutate(name = forcats::fct_reorder(name, desc(unemp_rate)))
g1 <- map_ %>%
ggplot() +
geom_sf(color = "white", aes(fill = unemp_rate)) +
geom_sf_text(aes(label = name), size = 2) +
scale_fill_gradient2(low = "brown", high = "green", midpoint = 16) +
theme_minimal() +
theme(legend.position = "none", axis.text = element_blank(), axis.title = element_blank(), panel.grid = element_blank())
g2 <- map_ %>%
ggplot(aes(x = unemp_rate, y = name, fill = unemp_rate)) +
geom_col() +
scale_fill_gradient2(low = "brown", high = "green", midpoint = 16) +
geom_text(aes(label = name, x = .5, hjust = 0)) +
geom_text(aes(label = unemp_rate), nudge_x = - .5, hjust = 1) +
theme_void() +
theme(legend.position = "none")
g1 + inset_element(g2, 0, .2, .9, 1)
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/ZeQN2.png
</details>
# 答案2
**得分**: 1
这有点复杂,因为这是一种非常非标准的制作图例的方式,但使用`scales`包的帮助并不太难。您可以首先创建自己的颜色比例尺,例如:
```R
library(scales)
my_pal <- seq_gradient_pal(low = 'brown', high = 'green')
my_scale <- col_numeric(palette = my_pal, domain = range(map$unemp_rate))
my_cols <- setNames(my_scale(map$unemp_rate), map$name)
然后使用以下代码创建图表:
ggplot(map) +
geom_sf(color = "white", aes(fill = name)) +
geom_sf_text(aes(label = name), size = 2) +
scale_fill_manual(
values = my_cols,
name = "失业率",
labels = setNames(paste(map$name, map$unemp_rate, sep = ': '), map$name)
)
英文:
This is a bit involved, since this is a pretty non-standard way of making a legend, but not too bad with help from the scales
package. You can make your own color scale first, e.g. like so:
library(scales)
my_pal <- seq_gradient_pal(low = 'brown', high = 'green')
my_scale <- col_numeric(palette = my_pal, domain = range(map$unemp_rate))
my_cols <- setNames(my_scale(map$unemp_rate), map$name)
ggplot(map) +
geom_sf(color = "white", aes(fill = name)) +
geom_sf_text(aes(label = name), size = 2) +
scale_fill_manual(
values = my_cols,
name = "Unemployment rate",
labels = setNames(paste(map$name, map$unemp_rate, sep = ': '), map$name)
)
答案3
得分: 0
你需要创建一个字段,将名称和失业率合并,并将其用作填充变量。另外,我不确定关于“颜色不对”的部分,但也许你想要一个连续的颜色比例尺?所以我正在使用viridis颜色调色板来获取类似的连续比例尺,但适用于分类数据。
map |>
mutate(fill_var = paste0(name, ' - ', unemp_rate)) |>
ggplot() +
geom_sf(color = "white", aes(fill = fill_var)) +
geom_sf_text(aes(label = name), size = 2) +
ggthemes::theme_map() + # optional
scale_fill_viridis_d() +
labs(fill = "")
<details>
<summary>英文:</summary>
You need to create a field which combines the name and unemployment rate and use that for the fill variable. Also I am not sure about the "colours are not right" part, but maybe you want a continuous colour scale? So I am using viridis colour palette to get similar continuous scale but for categorical data.
map |>
mutate(fill_var = paste0(name, ' - ', unemp_rate)) |>
ggplot() +
geom_sf(color = "white", aes(fill = fill_var)) +
geom_sf_text(aes(label = name), size = 2) +
ggthemes::theme_map() + # optional
scale_fill_viridis_d() +
labs(fill = "")
[![sample_plot_output_with_legends][1]][1]
[1]: https://i.stack.imgur.com/j6VOf.png
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论