操纵用于开发地图填充的极值 [英] Manipulate the extreme values used to develop fill in a map

查看:44
本文介绍了操纵用于开发地图填充的极值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 ggplot2 和一个名为 rnaturalearth 的包来开发欧洲国家的地图,根据每个国家的分数,每个国家都有不同的颜色.

问题:我想定义 ggplot2 在为每个国家/地区定义颜色时使用的值.现在,ggplot2 使用最低和最高值来定义尺度的极值;我想自己定义极端(即使用越来越低的极端值,从而操纵颜色).

数据:

Data <- structure(list(iso_a2 = structure(c("AT", "BE", "CH", "CZ", "DE",DK"、ES"、FI"、FR"、GB"、GR"、HU"、IE"、IT"、LU"、NL",NO"、PL"、PT"、SE"、SI")、标签 =国家/地区"、format.stata =%2s")、值 = c(0.498210763764124, 0.39731454174295, 1.28199768407053,-0.645219093750782, 0.0505441315876436, 1.91304897270232,0.0802428116303039, 1.40711329859048, 0.0627266707521129,0.191581882192026, 0.181001731032278, 0.356882787996765,0.168525492955127, 0.276086485962419, 1.12477750307519, 0.892265586989629,1.22957941831254, -0.942690852748792, -0.412722832958249,1.34589962077675, -0.484403677107108)), row.names = c(NA,-21L), class = c(data.frame"))

这是我当前正在运行的代码:

#加载包图书馆(tidyverse)图书馆(自然地球)# 使用rnaturalearth的地图,仅限欧洲国家世界 <- ne_countries(scale = "medium", returnclass = "sf")欧洲 <- world[which(world$continent == "Europe"), ]# 向地图添加数据数据 <- 合并(欧洲,数据,by = iso_a2",all = TRUE)# 用颜色绘制地图ggplot(数据)+geom_sf(aes(fill = -values), size = 0.25) +coord_sf(xlim = c(-10.8, 32), ylim = c(35, 71.3), expand=FALSE) +主题(legend.position =无")+主题(axis.text.x = element_blank(),axis.text.y = element_blank(),axis.ticks = element_blank(),panel.grid.major = element_blank(),panel.background = element_blank()) +scale_fill_continuous(na.value = "grey90")

结果是:

我不想通过定义颜色本身来操纵这些颜色,而是通过操纵 ggplot2 使用的比例(现在假设从 data$values 中的最低值到最高值).

使用 scale_fill_gradient 直接操作颜色不是一个好主意,因为 我正在开发几个地图 并且整个想法是 应该产生一个特定的值使用相同的颜色,与特定地图中表示的值无关.


编辑.我决定使用一个简单的解决方案,将两行添加到数据框中,并在所有地图上具有恒定的极值.

类似于:

<预><代码>df_high <- data.frame(SJ", 1.63, 2.2)df_low <- data.frame(AZ", -1.5, -2.02)名称(df_high)<- c(cntry",values_1",values_2")名称(df_low)<- c(cntry",values_1",values_2")new_map_2010 <- rbind(old_map_2010, df_high, df_low)new_map_2012 <- rbind(old_map_2012, df_high, df_low)

这不是程序员的解决方案,但对我来说,它比看起来是替代解决方案更容易.因此,我无法确定@Pedro Alencar 下面的解决方案是否有效.

所以请,如果有人尝试 Pedro Alencar 的建议并发现它有效,请告诉我,我会接受他的解决方案.目前,我只能点赞.

(我自己的解决方案可以很容易地通过使用代码来识别所有数据框中的最高和最低值,然后添加具有这些值的新行 - 并将这些特定行添加到所有数据框中.所有这些都用代码完成,但是仍然不是真正的程序员解决方案......)

解决方案

使用值(四舍五入)和颜色创建数据框:

df_colors <- data.frame(values_round = seq(round(min(Data$values, na.rm = T),2),轮(最大(数据$值,na.rm = T),2),由 = 0.01))df_colors$color <- grDevices::colorRampPalette(brewer.pal(9, "Blues"))(nrow(df_colors))df_colors$values_round <- as.integer(df_colors$values_round*100)

看到我将值转换为整数.这是因为我遇到了一些舍入错误.

然后在原始数据框 (Data) 和 left_join 中使用 df_colors 创建一个新列 values_round:

Data$values_round <- as.integer(round(Data$values, 2)*100)数据 <- left_join(Data, df_colors, by = 'values_round')

现在您可以绘制:

ggplot(Data) +geom_sf(aes(fill = color), size = 0.25) +coord_sf(xlim = c(-10.8, 32), ylim = c(35, 71.3), expand=FALSE) +主题(legend.position =无")+主题(axis.text.x = element_blank(),axis.text.y = element_blank(),axis.ticks = element_blank(),panel.grid.major = element_blank(),panel.background = element_blank()) +scale_colour_identity(美学=填充")

请注意,您需要确定整个数据集的最大值和最小值才能获得固定的 df_colors.

I use ggplot2 and a package called rnaturalearth to develop a map of European countries, with different colour for each country dependent on each country's score.

The problem: I want to define which value ggplot2 uses when defining colours for each country. Now, ggplot2 uses the lowest and highest values to define the extremes of the scale; I want to define the extremes by myself (that is, use lower and higher extreme values and thereby manipulate the colours).

Data:

Data <- structure(list(iso_a2 = structure(c("AT", "BE", "CH", "CZ", "DE", 
"DK", "ES", "FI", "FR", "GB", "GR", "HU", "IE", "IT", "LU", "NL", 
"NO", "PL", "PT", "SE", "SI"), label = "Country", format.stata = "%2s"), 
    values = c(0.498210763764124, 0.39731454174295, 1.28199768407053, 
    -0.645219093750782, 0.0505441315876436, 1.91304897270232, 
    0.0802428116303039, 1.40711329859048, 0.0627266707521129, 
    0.191581882192026, 0.181001731032278, 0.356882787996765, 
    0.168525492955127, 0.276086485962419, 1.12477750307519, 0.892265586989629, 
    1.22957941831254, -0.942690852748792, -0.412722832958249, 
    1.34589962077675, -0.484403677107108)), row.names = c(NA, 
-21L), class = c("data.frame"))

This is the code I'm currently running:

# Load packages
library(tidyverse)
library(rnaturalearth)

# Use map from rnaturalearth, restrict to European countries
world  <- ne_countries(scale = "medium", returnclass = "sf")
Europe <- world[which(world$continent == "Europe"), ]

# Add Data to the map
Data <- merge(Europe, Data, by = "iso_a2", all = TRUE)

# Draw map with colours
ggplot(Data) +
    geom_sf(aes(fill = -values), size = 0.25) +
    coord_sf(xlim = c(-10.8, 32), ylim = c(35, 71.3), expand=FALSE) +
    theme(legend.position = "none") +
    theme(
      axis.text.x = element_blank(),
      axis.text.y = element_blank(),
      axis.ticks = element_blank(),
      panel.grid.major = element_blank(),
      panel.background = element_blank()) +
    scale_fill_continuous(na.value = "grey90")

The result is:

I would like to manipulate these colours not by defining the colours per se, but by manipulating the scale ggplot2 uses (now presumable going from the lowest to the highest value in data$values).

Manipulating the colours directly by using scale_fill_gradient would not be a good idea since I am developing several maps and the whole idea is that a specific value should result in the same colour independently of what values are represented in the specific map.


EDIT. I have decided to use a simple solution, adding two rows to the data frame with constant extreme values across all maps.

Something like:


df_high <- data.frame("SJ",  1.63, 2.2)
df_low  <- data.frame("AZ", -1.5, -2.02)

names(df_high) <- c("cntry", "values_1", "values_2")
names(df_low)  <- c("cntry", "values_1", "values_2")

new_map_2010 <- rbind(old_map_2010, df_high, df_low)
new_map_2012 <- rbind(old_map_2012, df_high, df_low)

This is not a programmer's solution, but it is easier for me than what appears to be the alternative solution. Consequently, I am not able to decide whether the solution below by @Pedro Alencar works or not.

So PLEASE, if anyone tries Pedro Alencar's suggestion and finds it works, please tell me and I will accept his solution. For now, I can only upvote it.

(My own solution can easily be adapted by using code to identify the highest and lowest values across all data frames, then add new rows with these values - and add these specific rows to all data frames. All done with code, but still not really a programmer's solution...)

解决方案

Create a data frame with values (rounded) and colours:

df_colors <- data.frame(values_round = seq(round(min(Data$values, na.rm = T),2), 
                                    round(max(Data$values, na.rm = T),2),
                                    by = 0.01))
df_colors$color <- grDevices::colorRampPalette(brewer.pal(9, "Blues"))(nrow(df_colors))
df_colors$values_round <- as.integer(df_colors$values_round*100)

See that I turned the values to integer. This is because I was facing some rounding errors.

Then create a new column values_round in your original data frame (Data) and left_join with df_colors:

Data$values_round <- as.integer(round(Data$values, 2)*100)
Data <- left_join(Data, df_colors, by = 'values_round')

Now you can plot:

ggplot(Data) +
  geom_sf(aes(fill = color), size = 0.25) +
  coord_sf(xlim = c(-10.8, 32), ylim = c(35, 71.3), expand=FALSE) +
  theme(legend.position = "none") +
  theme(
    axis.text.x = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks = element_blank(),
    panel.grid.major = element_blank(),
    panel.background = element_blank()) +
  scale_colour_identity(aesthetics = "fill")

Note that you'll need to identify the maximum and minimum for your entire dataset in order to get a fixed df_colors.

这篇关于操纵用于开发地图填充的极值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆