Reputation: 23
I have a ggmap of California. The zip codes are clustered, from lower to uppper, five clusters total, and assigned colors based on their cluster. What I want to do is put a heat map layer over this based on population density.
I know I need to vary the alpha based on population density, which is simply called density in the data frame, but I don't know exactly how to do this. I have the layer on the map, but the alpha is constant, instead of varying by population density.
Here is my code:
First, generating a useable data frame:
stack_reduced_lng=c(-118.2495, -118.2467, -118.2737, -118.3108, -118.3065, -118.2942, -118.2849, -118.3471, -118.3158, -118.2587, -118.2382, -118.2403, -118.2665, -118.3546, -118.2643, -118.3172, -118.3387, -118.3099, -118.1561, -118.1999)
stack_reduced_lat=c( 33.97398, 33.94901, 33.96411, 34.07621, 34.05912, 34.04801, 34.02809, 34.00956, 34.06211, 34.00714, 34.06599, 34.04481, 34.03939, 34.02872, 34.05291, 34.02887, 34.04864, 34.06639, 34.02453, 34.02276)
stack_reduced_density=c( 6595.9, 6721.1, 8016.2, 7668.7, 14151.8, 11981.7, 6640.7, 3337.9, 3226.8, 10014.5, 4361.8, 7227.4, 5112.6, 4886.0, 14737.8, 7131.7, 6408.5, 13386.6, 5905.2, 4266.7)
stack_reduced_value.level=c( "Lower.Value", "Lower.Value", "Lower.Value", "Upper.Mid.Value", "Middle.Value", "Low.Mid.Value", "Low.Mid.Value", "Middle.Value", "Middle.Value", "Lower.Value", "Low.Mid.Value", "Middle.Value", "Middle.Value", "Low.Mid.Value", "Middle.Value", "Low.Mid.Value", "Middle.Value", "Low.Mid.Value", "Low.Mid.Value", "Low.Mid.Value")
df=as.data.frame(cbind(stack_reduced_lng, stack_reduced_lat, stack_reduced_density, stack_reduced_value.level))
colnames(df)=c("lng", "lat", "density", "value.level")
Next, the code to make the original ggmap:
#### First, our center
la.center=c(lng=-118.2437, lat=34.0522)
#### We will create a vector of colors, to be names and used in all project maps.
map_colors=c("black", "yellow", "green", "blue", "red")
#### creating our map
socal_map=get_map(location=la.center, zoom=6, scale=4)
d=ggmap(socal_map)+
geom_point(aes(x=lng, y=lat, color=as.factor(value.level)), data=df)
#ggtitle("Map of Home Values By Zip Code For California")
#### Formatting the map
d=d+scale_color_manual(, name="Home Value Level", breaks=c("Lower.Value","Low.Mid.Value","Middle.Value", "Upper.Mid.Value", "Upper.Value"), labels=c("Lower Home Value", "Lower Middle Home Value", "Middle Home Value", "Upper Middle Home Value", "Upper Home Value"), values=map_colors)+labs(x="Longititude", y="Latitude", title="Map of Home Values by Zip Code for California")
The above code creates the desired map, but I want to add a heat map layer to it.
Here is my attempt:
d+coord_cartesian()+stat_binhex(
aes(x=lng, y=lat, fill=density),
size=1, bins=20, alpha=0.5,
data=df
)
This adds a layer to my map, but the alpha is constant at 0.5, and is not varying with density. The map it produces has a constant layer over it, the alpha level, when it should vary with density.
EDIT:
I now have a solution.
The map generated above, called d in my code here, can take an added layer like this:
d+stat_density2d(data=cali.val.income.dat, aes(x=lng, y=lat, fill=density, alpha=..level..),
geom="polygon", size=1, bins=15)+
scale_alpha(range=c(0.1, 0.2))
Which gives what I want. I'm still fine tuning it, but using stat_density2d solved the problem.
I still need to label it a bit better, but this is what I was trying to do. The points are bsed on value level, the heat layer is based on density.
Thank you L Tyrone!!
Your help is much appreciated.
I'm not sure if I'm editing this correctly. I apologize, and will make the necessary corrections if it does not work.
Upvotes: 2
Views: 49
Reputation: 7225
You were almost there. There's a problem with your density values in your example data as they are strings (although I'm guessing the values in your real data are correct). Also, you declare fill
as density, but I'm guessing you wanted it as value.level? You can colour each hexagon by value.level and set the density in one step. Let me know if this is incorrect and I'll update my answer. Either way, this will give you a point to start from.
Note that I don't have an API key so this is a generalised solution. Comment below if this works for you.
library(ggplot2)
# Convert density to integers
df$density <- as.numeric(df$density)
ggplot() +
coord_cartesian() +
stat_binhex(data = df,
aes(x = lng, y = lat,
fill = value.level,
alpha = density),
# size = 1, # No discernible difference, may throw "deprecated" warning
bins = 20) +
scale_alpha_continuous(range=c(0.1, 0.5)) +
scale_fill_manual(values = c("#CC79A7", "#0072B2", "#E69F00", "#999999"))
Upvotes: 1