There are crimes everywhere. But I believe full-grown adults’ concern regarding crime and the concerns for a family with young kids are different. Crimes such as kidnapping should affect children more than adults. Drugs should be a more significant concern to parents than to a couple.
Although websites such as Trulia and Zillow offer crime map, each crime is different. In this EDA, we will figure out what type of crime infest San Francisco Bay Area.
The datasets are published at Kaggle (Link.) Kaggle has separated the files into a train, and test sets as their purpose is to classify the type of crime. Since we are doing an EDA, we will combine them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
##### Load Libraries ##### library(tidyverse) library(gridExtra) library(ggmap) ##### Theme ##### theme_moma <- function(base_size = 12, base_family = "Helvetica") { theme( plot.background = element_rect(fill = "#F7F6ED"), legend.key = element_rect(fill = "#F7F6ED"), legend.background = element_rect(fill = "#F7F6ED"), panel.background = element_rect(fill = "#F7F6ED"), panel.border = element_rect(colour = "black", fill = NA, linetype = "dashed"), panel.grid.minor = element_line(colour = "#7F7F7F", linetype = "dotted"), panel.grid.major = element_line(colour = "#7F7F7F", linetype = "dotted") ) } ##### Arrange Function ##### reorder <- function(x) { factor(x, levels = names(sort(table(x), decreasing = TRUE))) } ##### Dodge ##### dodgepos <- position_dodge(width=0.6) ##### Loading Data ##### train <- read.csv('train.csv') test <- read.csv('test.csv') #Putting type train <- mutate(train, type = "train") test <- mutate(test, type = "test") #Full_Join eda <- full_join(x=train, y=test) |
The data is already clean, so there is nothing much to do but just two simple things.
1 2 3 4 5 6 |
#Change Date Format to POSIXct eda$Dates <- as.POSIXct(eda$Dates) #Arrange day of week eda$DayOfWeek <- factor(eda$DayOfWeek, levels =c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday")) |
Okay, let’s see the data.
1 2 |
#Glimpse glimpse(eda) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
> glimpse(eda) Observations: 1,762,311 Variables: 11 $ Dates <dttm> 2015-05-13, 2015-05-13, 2015-05-13, 2015-05-13, 2015-05-13, 2015-05-13, 2015-... $ Category <fctr> WARRANTS, OTHER OFFENSES, OTHER OFFENSES, LARCENY/THEFT, LARCENY/THEFT, LARCE... $ Descript <fctr> WARRANT ARREST, TRAFFIC VIOLATION ARREST, TRAFFIC VIOLATION ARREST, GRAND THE... $ DayOfWeek <fctr> Wednesday, Wednesday, Wednesday, Wednesday, Wednesday, Wednesday, Wednesday, ... $ PdDistrict <fctr> NORTHERN, NORTHERN, NORTHERN, NORTHERN, PARK, INGLESIDE, INGLESIDE, BAYVIEW, ... $ Resolution <fctr> ARREST, BOOKED, ARREST, BOOKED, ARREST, BOOKED, NONE, NONE, NONE, NONE, NONE,... $ Address <chr> "OAK ST / LAGUNA ST", "OAK ST / LAGUNA ST", "VANNESS AV / GREENWICH ST", "1500... $ X <dbl> -122.4259, -122.4259, -122.4244, -122.4270, -122.4387, -122.4033, -122.4233, -... $ Y <dbl> 37.77460, 37.77460, 37.80041, 37.80087, 37.77154, 37.71343, 37.72514, 37.72756... $ type <chr> "train", "train", "train", "train", "train", "train", "train", "train", "train... $ Id <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... |
Almost 2 million observations of data. I would leave the “Address” variable alone. The “lon” and “lat” variables are particularly interesting to me.
As we will use it to for
ggmap() , I want to check if there is an error.
First, we need to get San Francisco coordinates.
1 2 |
##### San Francisco Coordinates ##### geocode("San Francisco") |
1 2 3 4 5 |
> ##### San Francisco Coordinates ##### > geocode("San Francisco") Information from URL : http://maps.googleapis.com/maps/api/geocode/json?address=San%20Francisco&sensor=false lon lat 1 -122.4194 37.77493 |
Okay, so SF’s lon and lats are -122.4194 and 37.77493.
Next, we need to check if the dataset has errors. As it is almost two million observations, I will not use geom_point but will use
geom_boxplot() instead.
1 2 3 4 5 6 |
##### Box Plot ##### ggplot(eda, aes(x = X, y = Y)) + geom_boxplot() + facet_grid(~type) + ggtitle("Inspecting Coordinates") + theme_moma() |
Oh, that is interesting. It is wrong. Longitude 90 is probably not even near San Francisco. Given that we have an outlier like this, it makes me want to see how the Y distributed in the dataset.
1 2 3 4 5 6 7 8 |
##### Box Plot - Only < 50 ##### eda %>% filter(Y < 90) %>% ggplot(aes(x = X, y = Y)) + geom_boxplot() + facet_grid(~type) + ggtitle("Inspecting Coordinates - 2") + theme_moma() |
Okay, that is much better. It seems like the only error in this dataset is the data point. At this point, instead of creating a new dataset, I’ll use pipe operator for visualization.
Next, we need to download a map through
ggmap() .
ggmap() can fetch data from Google, OSM, and Stamen with many map types.
In this case, I chose Stamen and terrain-lines for clear visualization.
1 2 3 4 5 6 |
##### Get Map ###### map <- get_map(location = "San Francisco", maptype = "terrain-lines", source="stamen", zoom = 12) ggmap(map, extent = "device") + theme_moma() |
Ah, that’s beautiful. Since we already got the map, first of all, I want to see the aerial view of “PdDistrict.”
It is unfortunate that my laptop cannot handle plotting geom_point on 800K observations. So I used 100,000 observations to plot on ggmap. It is not perfect. But we now know where each district is.
1 2 3 4 5 6 7 |
##### Locating PdDistrict ##### x <- train[1:100000,] ggmap(map, extent = "device", maprange = FALSE, legend = "bottom", base_layer=ggplot(x,aes(x=X,y=Y))) + geom_point(aes(col=PdDistrict)) + ggtitle("PdDistrict Location") + theme_moma() |
I guess that blue dots in the small island is the Alcatraz. So, let’s see what district is the most crime infested.
1 2 3 4 5 6 7 8 |
##### Most dangerous district ##### ggplot(eda, aes(x = reorder(PdDistrict))) + geom_bar(aes(y=(..count..)/sum(..count..)), alpha=0.6) + scale_y_continuous(labels = scales::percent) + geom_text(aes(label = scales::percent((..count..)/sum(..count..)), y= (..count..)/sum(..count..) ), stat= "count", vjust = -0.5) + ylab("Percentage") + xlab("District") + ggtitle("Crime Percentage by District") + theme_moma() |
It seems like Southern is the most dangerous as it accounted for around 18% of the crime. At this point, we know that what district is dangerous. Let’s explore the type of crime in the train dataset.
1 2 3 4 5 6 |
##### Overview Crime ##### ggplot(train, aes(x = reorder(Category))) + geom_bar() + coord_flip() + ylab("Category") + theme_moma() |
There are 39 types of crime in the dataset. As we assume that we are a family of four with two young kids, I think the offenses that are related to children are MISSING PERSON, KIDNAPPING, EXTORTION, and DRUG/NARCOTIC. We wouldn’t want our kids to get kidnapped,
or extorted, or to use drugs.
Instead of using pipe operator all the time, I’ll just create a new dataset for convenience and change the name a bit for easier visualization.
1 2 3 4 5 6 7 8 9 10 11 |
##### Creating Kids-Related Crimes ##### kids <- eda%>% filter(type == "train") %>% filter(Category == "KIDNAPPING" | Category == "EXTORTION" | Category == "MISSING PERSON" | Category == "DRUG/NARCOTIC") %>% mutate(Category = ifelse(Category == "KIDNAPPING","K", ifelse(Category == "EXTORTION","X", ifelse(Category == "MISSING PERSON","M","D")))) kids$Category <- as.factor(kids$Category) |
Now we are ready to see what are the areas we should avoid. But before we use a heat map to see the exact location, let’s see what type of crimes contributed the most in the areas.
1 2 3 4 5 6 |
##### Bar Chart Crime ##### ggplot(kids, aes(x=reorder(PdDistrict), fill = Category)) + geom_bar() + theme(legend.position = "bottom") + xlab("PdDistrict") + theme_moma() |
Oh, it seems like San Francisco has some serious issue with drugs. Tenderloin appears to be a hotbed of crime as it has count way higher than the rest. I’m quite interested in Bayview. Let’s look at a different view.
1 2 3 4 5 6 7 |
##### Bar Chart Crime - 2 ##### ggplot(kids, aes(x=PdDistrict, fill = Category)) + geom_bar() + theme(legend.position = "bottom", axis.text.x = element_text(angle=45, vjust=0.5, size=12)) + facet_wrap(~ Category) + theme_moma() |
So, that is interesting. Bayview seems to have particular a high number of missing person, while they rank 4th in term of all crime. Now, let’s use the heat map to determine where precisely these crimes occurred.
1 2 3 4 5 6 7 8 9 |
##### Heat Map ##### ggmap(map, extent = "device", legend = "bottom") + geom_density2d(data = kids, aes(x = X, y = Y), size = 0.3) + stat_density2d(data = kids, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_fill_gradient(low = "blue", high = "red") + #scale_color_brewer(palette = "Greens")+ scale_alpha( guide = FALSE) + #range = c(0, 0.3), theme_moma() |
I have to say that it is interesting. Tenderloin seems to be such a hotbed of crime that the algorithm concentrated the density at Tenderloin. But this is not good for our visualization as we want to see where it is. Let’s try this workaround.
1 2 3 4 5 6 7 8 9 |
##### Heat Map - 2 ##### ggmap(map, extent = "device", legend = "bottom") + geom_density2d(data = kids, aes(x = X, y = Y), size = 0.3) + stat_density2d(data = kids, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_fill_gradient(low = "blue", high = "red") + scale_alpha(guide = FALSE) + facet_wrap(~PdDistrict) + theme_moma() |
Okay, that’s better. But it is still too small, and if I were to put another layer, it would be too small to distinguish anyway. Let’s try another way.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
##### Separate District Data ##### kids_bayview <- kids %>% filter(PdDistrict == "BAYVIEW") kids_central <- kids %>% filter(PdDistrict == "CENTRAL") kids_ingleside <- kids %>% filter(PdDistrict == "INGLESIDE") kids_mission <- kids %>% filter(PdDistrict == "MISSION") kids_northern <- kids %>% filter(PdDistrict == "NORTHERN") kids_park <- kids %>% filter(PdDistrict == "PARK") kids_richmond <- kids %>% filter(PdDistrict == "RICHMOND") kids_southern <- kids %>% filter(PdDistrict == "SOUTHERN") kids_taraval <- kids %>% filter(PdDistrict == "TARAVAL") kids_ten <- kids %>% filter(PdDistrict == "TENDERLOIN") ##### Heat Map - 3 with geom_point() ##### ggmap(map, extent = "device", legend = "bottom") + geom_density2d(data = kids_central, aes(x = X, y = Y, col = "slateblue"), size = 0.9) + stat_density2d(data = kids_central, aes(x = X, y = Y, col = "slateblue", fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + geom_density2d(data = kids_bayview, aes(x = X, y = Y, col = "greens"), size = 0.9) + stat_density2d(data = kids_bayview, aes(x = X, y = Y, col = "greens", fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + geom_density2d(data = kids_ingleside, aes(x = X, y = Y, col = "blue"), size = 0.9) + stat_density2d(data = kids_ingleside, aes(x = X, y = Y, col = "blue", fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + geom_density2d(data = kids_mission, aes(x = X, y = Y, col = "turquoise1"), size = 0.9) + stat_density2d(data = kids_mission, aes(x = X, y = Y, col = "turquoise1", fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + geom_density2d(data = kids_northern, aes(x = X, y = Y, col = "yellow"), size = 0.9) + stat_density2d(data = kids_northern, aes(x = X, y = Y, col = "yellow", fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + geom_density2d(data = kids_park, aes(x = X, y = Y, col = "seagreen"), size = 0.9) + stat_density2d(data = kids_park, aes(x = X, y = Y, col = "seagreen", fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + geom_density2d(data = kids_richmond, aes(x = X, y = Y, col = "salmon"), size = 0.9) + stat_density2d(data = kids_richmond, aes(x = X, y = Y, col = "salmon", fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + geom_density2d(data = kids_southern, aes(x = X, y = Y, col = "purple"), size = 0.9) + stat_density2d(data = kids_southern, aes(x = X, y = Y, col = "purple", fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + geom_density2d(data = kids_taraval, aes(x = X, y = Y, col = "azure"), size = 0.9) + stat_density2d(data = kids_taraval, aes(x = X, y = Y, col = "azure", fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + geom_density2d(data = kids_ten, aes(x = X, y = Y, col = "red"), size = 0.9) + stat_density2d(data = kids_ten, aes(x = X, y = Y, col = "red", fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(guide = FALSE) + theme_moma() |
I feel like the area closed to Tenderloin is a hotbed of crime. They are just so concentrated in that area. So, Northeast San Francisco is not the place where we should go specifically Tenderloin and regions adjacent to Tenderloin. But if you could recall, you would notice that there are crimes in the entire Bay Area.
But not all in the above picture is covered by the stat_density. For example, crimes in Bayview mainly concentrated in just a specific area while the rest of the area has significantly much fewer occurrences. So, Tenderloin is off the list for sure as the entire area is infested with crime. But the others seem to have both safe and unsafe areas, let’s take a look at one by one.
1 2 3 4 5 6 7 8 9 10 11 12 |
##### Bayview Map and Point ##### map_bayview <- get_map(location = c(-122.381804, 37.731121), maptype = "terrain-lines", source="stamen", zoom = 13) ggmap(map_bayview, extent = "device", legend = "bottom") + geom_density2d(data = kids_bayview, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kids_bayview, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y, col = Category),data = kids_bayview, alpha = 0.5) + ggtitle("Bayview") + theme_moma() |
1 2 3 4 5 6 7 8 9 10 11 12 |
##### Southern Map and Point ##### map_southern <- get_map(location = c(-122.402747, 37.778895), maptype = "terrain-lines", source="stamen", zoom = 13) ggmap(map_southern, extent = "device", legend = "bottom") + geom_density2d(data = kids_southern, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kids_southern, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y, col = Category),data = kids_southern, alpha = 0.5) + ggtitle("Southern") + theme_moma() |
1 2 3 4 5 6 7 8 9 10 11 12 |
##### Central Map and Point ##### map_central<- get_map(location = c(-122.416823, 37.794632), maptype = "terrain-lines", source="stamen", zoom = 13) ggmap(map_central, extent = "device", legend = "bottom") + geom_density2d(data = kids_central, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kids_central, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y, col = Category),data = kids_central, alpha = 0.5) + ggtitle("Central") + theme_moma() |
1 2 3 4 5 6 7 8 9 10 11 12 |
##### Northern Map and Point ###### map_northern<- get_map(location = c(-122.426292, 37.795291), maptype = "terrain-lines", source="stamen", zoom = 13) ggmap(map_northern, extent = "device", legend = "bottom") + geom_density2d(data = kids_northern, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kids_northern, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y, col = Category),data = kids_northern, alpha = 0.5) + ggtitle("Northern") + theme_moma() |
1 2 3 4 5 6 7 8 9 10 11 12 |
##### Mission Map and Point ###### map_mission<- get_map(location = c(-122.428867, 37.772634), maptype = "terrain-lines", source="stamen", zoom = 13) ggmap(map_mission, extent = "device", legend = "bottom") + geom_density2d(data = kids_mission, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kids_mission, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y, col = Category),data = kids_mission, alpha = 0.5) + ggtitle("mission") + theme_moma() |
1 2 3 4 5 6 7 8 9 10 11 12 |
##### Ingleside Map and Point ###### map_ingleside<- get_map(location = c(-122.428352, 37.744948), maptype = "terrain-lines", source="stamen", zoom = 13) ggmap(map_ingleside, extent = "device", legend = "bottom") + geom_density2d(data = kids_ingleside, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kids_ingleside, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y, col = Category),data = kids_ingleside, alpha = 0.5) + ggtitle("ingleside") + theme_moma() |
1 2 3 4 5 6 7 8 9 10 11 12 |
##### Taraval Map and Point ###### map_taraval<- get_map(location = c(-122.496130, 37.738452), maptype = "terrain-lines", source="stamen", zoom = 13) ggmap(map_taraval, extent = "device", legend = "bottom") + geom_density2d(data = kids_taraval, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kids_taraval, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y, col = Category),data = kids_taraval, alpha = 0.5) + ggtitle("Taraval") + theme_moma() |
1 2 3 4 5 6 7 8 9 10 11 12 |
##### Richmond Map and Point ###### map_richmond<- get_map(location = c(-122.487204, 37.781066), maptype = "terrain-lines", source="stamen", zoom = 13) ggmap(map_richmond, extent = "device", legend = "bottom") + geom_density2d(data = kids_richmond, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kids_richmond, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y, col = Category),data = kids_richmond, alpha = 0.5) + ggtitle("Richmond") + theme_moma() |
1 2 3 4 5 6 7 8 9 10 11 |
##### Park Map and Point ###### map_park<- get_map(location = c(-122.457678, 37.761797), maptype = "terrain-lines", source ="stamen", zoom = 13) ggmap(map_park, extent = "device", legend = "bottom") + geom_density2d(data = kids_park, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kids_park, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y, col = Category),data = kids_park, alpha = 0.5) + ggtitle("Park") + theme_moma() |
What about areas adjacent to Park and Mission.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
##### Adjacents to Park ##### ggmap(map_park, extent = "device", legend = "bottom") + geom_density2d(data = kids_park, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kids_park, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y, col = Category),data = kids_park, alpha = 0.5) + geom_point(aes(x = X, y = Y, col = Category),data = kids_richmond, alpha = 0.5) + geom_point(aes(x = X, y = Y, col = Category),data = kids_taraval, alpha = 0.5) + geom_point(aes(x = X, y = Y, col = Category),data = kids_northern, alpha = 0.5) + geom_point(aes(x = X, y = Y, col = Category),data = kids_ingleside, alpha = 0.5) + geom_point(aes(x = X, y = Y, col = Category),data = kids_mission, alpha = 0.5) + ggtitle("Adjacents to Park") + theme_moma() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
##### Mission and Adjacents ##### ggmap(map_mission, extent = "device", legend = "bottom") + geom_density2d(data = kids_mission, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kids_mission, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y, col = Category),data = kids_mission, alpha = 0.5) + geom_point(aes(x = X, y = Y, col = Category),data = kids_bayview, alpha = 0.5) + geom_point(aes(x = X, y = Y, col = Category),data = kids_northern, alpha = 0.5) + geom_point(aes(x = X, y = Y, col = Category),data = kids_southern, alpha = 0.5) + geom_point(aes(x = X, y = Y, col = Category),data = kids_central, alpha = 0.5) + geom_point(aes(x = X, y = Y, col = Category),data = kids_ten, alpha = 0.5) + ggtitle("Adjacents to Mission") + theme_moma() |
We now know what specific areas in each district we should settle down. Also, we should steer clear from the area adjacents to high crime districts.
A farewell note, I’d like to take a look at Kidnapping map.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
##### Filter Kidnapping ##### kidnapping <- eda%>% filter(type == "train") %>% filter(Category == "KIDNAPPING") ##### Geom_point Kidnapping ##### ggmap(map, extent = "device", legend = "bottom") + geom_density2d(data = kidnapping, aes(x = X, y = Y), size = 0.9) + stat_density2d(data = kidnapping, aes(x = X, y = Y, fill = ..level.., alpha = ..level..), size = 0.01, bins = 16, geom = "polygon") + scale_alpha(range = c(0, 0.3), guide = FALSE) + geom_point(aes(x = X, y = Y), data = kidnapping, alpha = 0.5) + ggtitle("Kidnapping") + theme_moma() |
TL;DR Stay away from Tenderloin and its adjacent areas.