Here is what I'm trying to do:
- I have two data frames for IL (for example), each data frame has a column to indicate if the counties should be mask or not.
- I will mapping those two data frames, side by side using
facet_wrap()
, and using my own created color bar,which is from blue to red with mean set to white. - For counties with
mask=1
, I need to mask those counties.
And my questions are:
- Right now I am using the grey color to mask the areas, but it is very ugly. I saw some published paper using the white background square with lines (like a shadow area) for masking. I don't know how to call that so I don't even know how to google search for that. If the legend can be used, how should I create the masking layer and put a separate legend for that other than a single color bar?
The legend is like:
- I created a separate data frame called
df_mask
, basically picking out the rows withmask=1
. Then usedgeom_polygon
to plot that data frame. Is that a way avoid doing that? Since I already have a column ofmask
in my data frame. For example, like a discrete fill, with 0 being transparent, and 1 being the shadow area. - Right now my masking layer also mask the border between counties, that why I set
alpha=0.9
so that I can kind of see the broader, however, that's too ugly... I want to mask the counties without masking the broaders.
Here is my sample code to generate my current plot:
library(RColorBrewer)
library(dplyr)
library(gridExtra)
library(ggplot2)
library(maptools)
library(ggmap)
library(RColorBrewer)
library(colorRamps)
map_il = map_data('county','illinois')
head(map_il)
#create a fake data to plot
counties = unique(map_il$subregion)
n=length(counties)
#fake data 1
df1 = data.frame(subregion=counties, value=runif(n),id=1,mask=sample(0:1,n,TRUE))
df2 = data.frame(subregion=counties, value=runif(n),id=2,mask=sample(0:1,n,TRUE))
merged_df_1 = merge(map_il,df1,sort=FALSE,by='subregion')
merged_df_1 = merged_df_1[order(merged_df_1$order),]
merged_df_2 = merge(map_il,df2,sort=FALSE,by='subregion')
merged_df_2 = merged_df_2[order(merged_df_2$order),]
#set the two df to plot, using facet_wrap and id to seperate
df = rbind(merged_df_1,merged_df_2)
dim(df)
head(df)
#Choose my own color scale, I want the color from blue to red, with white
#stands for the mean of the two plots
get_color = function(c_v){
return(rgb(c_v[1], c_v[2], c_v[3]))
}
get_color_vector = function(z_min,z_max,z_mean,green_lim=NA){
#nin <- 256
nin <- 1000
nzero <- floor(1 + nin*(z_mean - z_min)/(z_max-z_min))
maxblue <- .7
maxred <- .7
colors <- matrix(NA, nin, 3)
colors[1:nzero,3] <- 1
colors[1:nzero,2] <- seq(1 - maxblue, 1, length.out = nzero)
colors[1:nzero,1] <- colors[1:nzero,2]
ix <- (nzero+1):nin
colors[ix, 1] <- 1
colors[ix, 2] <- seq(1, 1 - maxred, length.out = nin - nzero)
colors[ix, 3] <- colors[ix, 2]
if(!is.na(green_lim)){
colors[,2] <- seq(green_lim[1],green_lim[2], length.out = nin)
}
col_vector <- apply(colors, 1, get_color)
return(col_vector)
}
avg = mean(c(df1$value, df2$value))
r_min = min(c(df1$value, df2$value))
r_max = max(c(df1$value, df2$value))
color_vector = get_color_vector(r_min, r_max, avg)
#creat another data frame to make
df_mask = df[df$mask==1,]
#make the plot
qplot(long, lat, data = df, group = group, fill = value,
geom = "polygon")+
scale_fill_gradientn("",colours=color_vector,limits=c(r_min,r_max),
breaks=c(r_min,avg,r_max),
labels=c(round(r_min),"Avg",round(r_max)))+
labs(fill='',x="",y="")+
ggtitle('Sample plot')+
theme_bw()+facet_wrap(~id,ncol=2)+
geom_path( data = df , colour = "black")+
geom_polygon(data=df_mask,fill='grey',alpha=0.9)+
theme(plot.title = element_text(size=12),
strip.text.x = element_text(size = 8, colour = "black", angle = 0),
legend.text = element_text(size=6))