Одним из решений будет создание двух графиков и их объединение с использованием функции grid.arrange
из пакета gridExtra
, например
Сначала я конвертирую ваш растровый слой в таблицу, используя функцию, опубликованную в этом сообщении: Наложение растрового слоя на карту в ggplot2 в R?
(PS: я изменил ваш val
объект, чтобы сделать только 16 различных цветов, соответствующих заданному вами цветному рисунку. В вашем примере , val
имеет 20 различных значений)
val <- c(101:104, 201:204, 301:304, 401:404) # correction from OP's question to match 16 different values
library(raster)
gplot_data <- function(x, maxpixels = 50000) {
x <- raster::sampleRegular(x, maxpixels, asRaster = TRUE)
coords <- raster::xyFromCell(x, seq_len(raster::ncell(x)))
## Extract values
dat <- utils::stack(as.data.frame(raster::getValues(x)))
names(dat) <- c('value', 'variable')
dat <- dplyr::as.tbl(data.frame(coords, dat))
if (!is.null(levels(x))) {
dat <- dplyr::left_join(dat, levels(x)[[1]],
by = c("value" = "ID"))
}
dat
}
df <- gplot_data(plot.me)
Затем я создаю первый график, тепловую карту, используя geom_tile
:
library(ggplot2)
plot <- ggplot(df, aes(x = x, y = y, fill = as.factor(value)))+
geom_tile(show.legend = FALSE)+
coord_fixed(ratio = 20/20)+
scale_fill_manual(values = c("#beffff","#73dfff","#d0ff73","#55ff00",
"#73b2ff","#0070ff","#70a800","#267300",
"#f5f57a","#ffff00","#e8beff","#df73ff",
"#f5ca7a","#ffaa00","#e600a9","#a80084"))+
scale_y_continuous(name = "Latitude",labels = paste(c(40,45,50,55,60),"°N"))+
scale_x_continuous(name = "Longitude",labels = paste(c(-110,-105,-100,-95,-90),"°W"))+
theme_linedraw()+
theme(panel.border = element_rect(size = 2),
axis.text = element_text(size = 10),
axis.title = element_text(size = 10),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank())
Затем я создаю отдельный кадр данных для Легенда:
library(tidyverse)
df_legend <- data.frame(value = unique(df$value))
df_legend <- df_legend %>% rowwise() %>%
mutate(Dim1 = unlist(strsplit(as.character(value),""))[1],
Dim3 = unlist(strsplit(as.character(value),""))[3])
Source: local data frame [16 x 3]
Groups: <by row>
# A tibble: 16 x 3
value Dim1 Dim3
<int> <chr> <chr>
1 404 4 4
2 204 2 4
3 304 3 4
4 104 1 4
5 202 2 2
6 302 3 2
7 203 2 3
8 301 3 1
9 402 4 2
10 401 4 1
11 303 3 3
12 102 1 2
13 201 2 1
14 103 1 3
15 403 4 3
16 101 1 1
Теперь я создал сюжет для легенды:
legend <- ggplot(df_legend, aes(x = as.factor(Dim1), y = as.factor(Dim3), fill = as.factor(value)))+
geom_tile(show.legend = FALSE, color = "black")+
coord_fixed(ratio = 1)+
scale_fill_manual(values = c("#beffff","#73dfff","#d0ff73","#55ff00",
"#73b2ff","#0070ff","#70a800","#267300",
"#f5f57a","#ffff00","#e8beff","#df73ff",
"#f5ca7a","#ffaa00","#e600a9","#a80084"))+
theme_linedraw()+
labs(x = "Dim1", y = "Dim3")+
theme(panel.border = element_rect(size = 2),
axis.text = element_text(size = 10),
axis.title = element_text(size = 10))
И, наконец, я объединяю их:
library(gridExtra)
grid.arrange(plot, legend, layout_matrix = rbind(c(1,1,2),c(1,1,3)))
Это выглядит, что вы пытаетесь получить?
Примечание: вы, вероятно, можете нанести ваш растровый объект непосредственно на ggplot2
, но я не был уверен в точной процедуре. Также вы можете поиграть с макетом grid.arrange
, чтобы сюжет выглядел именно так, как вы хотите