如何使用ggplot2中的shapefile从第一幅图保留scale_fill_color

问题描述 投票:0回答:2

我需要使用ggplot2中的shapefile来帮助scale_fill_manual。我尝试了很多事情,终于发布了,希望有人能够给我提示。我基本上是在绘制一个shapefile并使用scale_fill_manual将其可视化使用自定义颜色,然后在上面覆盖一点,但是当我尝试添加我在图例中的新点,我原来的颜色在那里,但所有值都得到了弄乱。绘制shapefile的上部工作正常,但下部在覆盖新点时,我需要帮助。我有一些内联评论。见下文:下载shapefile的路径为:https://login.filesanywhere.com/fs/v.aspx?v=8c6a66875b6574bbaa68

library(tidyverse)
library(rgdal)
library(maptools)
library(plyr)
library(sp)
library(geosphere)
library(data.table)
library(rgeos)

wolves.map <- readOGR(dsn=".", layer="PNW_wolf_habitat_grid")
 message(proj4string(wolves.map)) # it is in Albers Equal Area projection.

 #Select presence/abscense only (1 and 0)
wolfsub <- wolves.map[!wolves.map$WOLVES_99 %in% 2,]
wolfsub$MAJOR_LC <-as.numeric(as.character(wolfsub$MAJOR_LC))

# Add columns to the wolfsub dataset. 42 = Forest, 51 = Shrub, > 81 = Agriculture
wolfsub$Forest<-ifelse(wolfsub$MAJOR_LC==42,1,0)
wolfsub$Shrub<-ifelse(wolfsub$MAJOR_LC==51,1,0)
wolfsub$Agriculture <- ifelse(wolfsub$MAJOR_LC > 81,1,0)

# create the model
mod1<-glm(WOLVES_99 ~ RD_DENSITY + Forest + Shrub + Agriculture,family = binomial,data = wolfsub)
summary(mod1)

#fitted(mod1)
wolfsub$WOLVES_99pred <- fitted(mod1) # add the predicted values to wolfsub

# Convert the wolves.map shapefile to data.frame
wolves.mapDF <- as.data.frame(wolves.map)

#fortify wolves.map to be used with ggplot2
wolves.ds <- fortify(wolves.map,region="GRID2_ID")

 # Rename the 'GRID2'_ID to 'id' to to be able to merge with the shapefile wolves.map
 wolves.mapDF <- rename(wolves.mapDF,c(GRID2_ID="id"))

# merge the shapefile wolves.ds and wolves.mapDF dataframe to be able to use the wolves.mapDF variables with ggplot2
wolves.ggmap <- merge(wolves.ds, wolves.mapDF, by = "id", all = TRUE)
wolves.ggmap <- wolves.ggmap[order(wolves.ggmap$order), ]

 wolves.ggmap$MAJOR_LC <-as.numeric(as.character(wolves.ggmap$MAJOR_LC))

 ### Now do the whole data set
 # 42 = Forest, 51 = Shrub, > 81 = Agriculture
wolves.ggmap$Forest<-ifelse(wolves.ggmap$MAJOR_LC==42,1,0)
wolves.ggmap$Shrub<-ifelse(wolves.ggmap$MAJOR_LC==51,1,0)
wolves.ggmap$Agriculture<-ifelse(wolves.ggmap$MAJOR_LC>81,1,0)

# Predict probabilities for the whole dataset
wolves.ggmap$PredictedSuit <- predict(mod1,newdata=wolves.ggmap,type='response')

#Make PredictedSuit a factor
wolves.ggmap$DiscretePred <- cut(wolves.ggmap$PredictedSuit,breaks=c(0,0.29,0.40,0.45,0.6,0.69),dig.lab = 2,include.lowest=TRUE)

 #plot and display a legend with the new cuts
Palette1 <- c('grey80','orange','yellow','green','green3','blue')
wolves.pred3 <- ggplot(wolves.ggmap,aes(long,lat,group=group)) + theme_bw() + theme_void() +  
geom_polygon(aes(fill=DiscretePred), colour = alpha("white", 1/2), size = 0.2) + theme(legend.position = c(0.14, 0.16)) +
scale_fill_manual(values=Palette1)  + guides(fill=guide_legend(ncol=2,"Predicted\n Suitability\n > 0.45"))  
wolves.pred3 

我得到以下图表(好):enter image description here

以上所有代码均按预期工作。我遇到的问题在下面...

#The code below works well overlaying the points from a subset of the same shapefile above,
#however, I lose my scale_fill_manual colors when I try to add the new points to the legend.
###################################################################################     
#Extract wolves from 2001 first and overlay them on map
wolfsub_01 <- wolves.map[wolves.map$WOLVES_01 %in% 1,]
wolfsub_01$MAJOR_LC <-as.numeric(as.character(wolfsub_01$MAJOR_LC))

#Get centroids to overlay on existing plot
test <- gCentroid(wolfsub_01, byid = TRUE)

#Convert to dataframe to be used with ggplot2
wolf <- as.data.frame(wolfsub_01) 
test <- as.data.frame(test)  
 wolves_test <- cbind(wolf,test)

 #Overlay on existing plot
wolves.pred3 + geom_point(data=wolves_test,aes(x,y,group=NULL,fill='2001 wolves'),color='blue') 
 ###########################################################################################
#If I try to include '2001 wolves' in my legend, my colors stay in the correct order,
#however, my legend values get all messed up. I tried
#to re-arrange them with a different palette but it only makes it worse because
#the colors and labels don't line up with the corresponding color.
#I also would like help with removing the dots from the legend.
#How can I get my colors back to my original Palette1 used above on the original plot?
#Probably a simple thing but I have spent many hours trying and can't figure it out.
#Thanks beforehand....

我得到这个情节。请注意,所有值均已结束。我需要这些值与第一个图的顺序相同。enter image description here

编辑:这是我的情节在后台显示的内容。第一个图具有以下颜色顺序:

> g <- ggplot_build(wolves.pred3)
> unique(g$data[[1]]["fill"])
      fill
1   grey80
9   orange
115 yellow
241 green3
271  green

而且我的第二个情节具有与第一个不同的颜色顺序。我想知道如何使第二个匹配第一个颜色顺序。

> g <- ggplot_build(a)
    > unique(g$data[[1]]["fill"])
          fill
    1   green3
    9   grey80
    115 orange
    241  green
    271 yellow
    > 
r ggplot2 sp rgdal maptools
2个回答
0
投票

我不够帅,无法发表评论,但我不确定您是否需要点缀填充美感。向填充比例添加新值可能会改变颜色。如果删除它不起作用,请尝试在fill=NA内而不是geom_point()内加点aes()


0
投票

这是我为您尝试的。我遍历了所有代码,并以为您认为我使数据处理变得复杂。我曾经使用sp方法编写类似您的代码。我个人认为这种方法使您“扭曲”某个地方的数据。在这里,我以另一种方式编写了您的代码,以实现预期的结果。我在下面的脚本中留下了解释。

library(sf)
library(dplyr)
library(ggplot2)
library(rgeos)

# You can use the sf package to read a shapefile.
wolves.map <- st_read(dsn = ".", layer = "PNW_wolf_habitat_grid")

# Step 1
# Sub data
# Select presence/abscense only (1 and 0)
# You used base R to write your script. The sp class objects do not accept
# tidyverse ways. But sf objects can take tidyverse ways, which makes your life much easier.

wolfsub <- filter(wolves.map, WOLVES_99 != 2) %>% 
            mutate(Forest = if_else(MAJOR_LC == 42, 1, 0),
                   Shrub = if_else(MAJOR_LC == 51, 1, 0),
                   Agriculture = if_else(MAJOR_LC > 81, 1, 0))

# Create the model
mod1 <- glm(WOLVES_99 ~ RD_DENSITY + Forest + Shrub + Agriculture, family = binomial, data = wolfsub)
summary(mod1)

# Fitted(mod1)
wolfsub$WOLVES_99pred <- fitted(mod1) # add the predicted values to wolfsub


# Step 2: Whole data
# Here I can avoid creating a new data frame for ggplot2. I saw that you worked
# to arrange a new data frame with all numbers. But that is not necessary any more.

wolves.map %>% 
mutate(Forest = if_else(MAJOR_LC == 42, 1, 0),
       Shrub = if_else(MAJOR_LC == 51, 1, 0),
       Agriculture = if_else(MAJOR_LC > 81, 1, 0)) -> wolves.map 

wolves.map$PredictedSuit <- predict(mod1,newdata = wolves.map,type = 'response')


mutate(wolves.map,
       DiscretePred = cut(PredictedSuit,
                          breaks = c(0,0.29,0.40,0.45,0.6,0.69),
                          dig.lab = 2,include.lowest = TRUE)) -> out

# Plot and display a legend with the new cuts
Palette1 <- c('grey80','orange','yellow','green','green3','blue')

ggplot() +
geom_sf(data = out, aes(fill = DiscretePred),
        colour = alpha("white", 1/2), size = 0.2) +
scale_fill_manual(values = Palette1)  +
theme_bw() +
theme_void() + 
theme(legend.position = c(0.14, 0.16)) +
guides(fill = guide_legend(ncol = 2,"Predicted\n Suitability\n > 0.45")) -> g

enter image description here

# Step 3
# Extract wolves from 2001 first and overlay them on map

wolfsub_01 <- filter(wolves.map, WOLVES_01 == 1)

# Get centroids to overlay on existing plot. I used st_centroid() instead of Gcentroid(). Then, I added long and lat to the original data frame, wolfsub_01

test <- bind_cols(wolfsub_01,
                  as.data.frame(st_coordinates(st_centroid(wolfsub_01))))

# Finally, I am adding a new layer to the previous graphic.

g +
geom_point(data = test, aes(x = X, y = Y), color = 'blue') -> gg

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.