In [2]:
# Import dependencies
import folium
import numpy as np
import pandas as pd

# Load accident data.
accident_data = pd.read_csv('./data/NYPD_Motor_Vehicle_Collisions_sampled.csv')

In [4]:
accident_data.head()


Out[4]:
DATE TIME BOROUGH ZIP CODE LATITUDE LONGITUDE LOCATION ON STREET NAME CROSS STREET NAME OFF STREET NAME ... CONTRIBUTING FACTOR VEHICLE 2 CONTRIBUTING FACTOR VEHICLE 3 CONTRIBUTING FACTOR VEHICLE 4 CONTRIBUTING FACTOR VEHICLE 5 UNIQUE KEY VEHICLE TYPE CODE 1 VEHICLE TYPE CODE 2 VEHICLE TYPE CODE 3 VEHICLE TYPE CODE 4 VEHICLE TYPE CODE 5
0 06/18/2016 5:20 BRONX 10456.0 40.824067 -73.908710 (40.8240665, -73.9087095) EAST 163 STREET 3 AVENUE NaN ... Unspecified NaN NaN NaN 3463614 PASSENGER VEHICLE NaN NaN NaN NaN
1 06/18/2016 7:10 BRONX 10472.0 40.826916 -73.872030 (40.8269163, -73.8720302) METCALF AVENUE WATSON AVENUE NaN ... Unspecified NaN NaN NaN 3464214 PASSENGER VEHICLE PASSENGER VEHICLE NaN NaN NaN
2 06/18/2016 7:20 NaN NaN 40.701455 -73.989620 (40.7014547, -73.9896203) NaN NaN NaN ... Unspecified NaN NaN NaN 3463782 PASSENGER VEHICLE PASSENGER VEHICLE NaN NaN NaN
3 06/18/2016 7:30 NaN NaN NaN NaN NaN 47 STREET NaN NaN ... Unspecified NaN NaN NaN 3465413 PASSENGER VEHICLE OTHER NaN NaN NaN
4 06/18/2016 7:45 QUEENS 11422.0 40.665256 -73.735334 (40.665256, -73.7353338) SOUTH CONDUIT AVENUE FRANCIS LEWIS BOULEVARD NaN ... Unspecified NaN NaN NaN 3463318 PASSENGER VEHICLE PASSENGER VEHICLE NaN NaN NaN

5 rows × 29 columns


In [5]:
accident_data.describe()


Out[5]:
ZIP CODE LATITUDE LONGITUDE NUMBER OF PERSONS INJURED NUMBER OF PERSONS KILLED NUMBER OF PEDESTRIANS INJURED NUMBER OF PEDESTRIANS KILLED NUMBER OF CYCLIST INJURED NUMBER OF CYCLIST KILLED NUMBER OF MOTORIST INJURED NUMBER OF MOTORIST KILLED UNIQUE KEY
count 6395.000000 6687.000000 6687.000000 10000.000000 10000.000000 10000.000000 10000.000000 10000.000000 10000.0 10000.000000 10000.000000 1.000000e+04
mean 10846.141048 40.723501 -73.917075 0.253500 0.000900 0.057600 0.000600 0.013900 0.0 0.206300 0.000400 3.554134e+06
std 554.570810 0.079065 0.086132 0.625361 0.029988 0.260939 0.024489 0.131562 0.0 0.702417 0.024493 1.272283e+05
min 10000.000000 40.504925 -74.247136 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 0.000000 1.259120e+05
25% 10309.000000 40.667784 -73.974463 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 0.000000 3.525040e+06
50% 11207.000000 40.721536 -73.926085 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 0.000000 3.586995e+06
75% 11238.000000 40.767516 -73.861872 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 0.000000 3.605235e+06
max 11697.000000 40.912295 -73.700597 12.000000 1.000000 6.000000 1.000000 3.000000 0.0 14.000000 2.000000 3.612908e+06

In [6]:
# Num rows in data.
print(accident_data.count())


DATE                             10000
TIME                             10000
BOROUGH                           6396
ZIP CODE                          6395
LATITUDE                          6687
LONGITUDE                         6687
LOCATION                          6687
ON STREET NAME                    6610
CROSS STREET NAME                 5197
OFF STREET NAME                   2174
NUMBER OF PERSONS INJURED        10000
NUMBER OF PERSONS KILLED         10000
NUMBER OF PEDESTRIANS INJURED    10000
NUMBER OF PEDESTRIANS KILLED     10000
NUMBER OF CYCLIST INJURED        10000
NUMBER OF CYCLIST KILLED         10000
NUMBER OF MOTORIST INJURED       10000
NUMBER OF MOTORIST KILLED        10000
CONTRIBUTING FACTOR VEHICLE 1     9950
CONTRIBUTING FACTOR VEHICLE 2     8320
CONTRIBUTING FACTOR VEHICLE 3      700
CONTRIBUTING FACTOR VEHICLE 4      196
CONTRIBUTING FACTOR VEHICLE 5       40
UNIQUE KEY                       10000
VEHICLE TYPE CODE 1               9779
VEHICLE TYPE CODE 2               7002
VEHICLE TYPE CODE 3                623
VEHICLE TYPE CODE 4                173
VEHICLE TYPE CODE 5                 34
dtype: int64

In [3]:
# Map data.

# Starting coordinates to load map view.
NYC_coordinates = (40.7142700, -74.0059700)

# Create Map object.
map = folium.Map(location=NYC_coordinates,
                     zoom_start=12)

# Creating different tile layers 
cycle_tile = folium.TileLayer(tiles = 'http://b.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', attr='Attributed').add_to(map)
cycle_tile.layer_name = 'Cycling Route Map'

# Create a feature group for controlling multiple aspects

col_group = folium.FeatureGroup(name='Collisions').add_to(map)
injury_group = folium.FeatureGroup(name='Injuries').add_to(map)


# Plot accidents.
# Limit number of points to plot for testing.
MAX_RECORDS = 1000
collision_cluster = folium.MarkerCluster().add_to(col_group)
for row in accident_data[0:MAX_RECORDS].iterrows():
    # Only plot point if lat/long is available.
    if (not np.isnan(row[1]['LATITUDE']) and not np.isnan(row[1]['LONGITUDE'])):
        accident_metadata = """
                <ul>
                    <li><strong>On street</strong>: {0}</li>
                    <li><strong>Cross street</strong>: {1}</li>
                    <li><strong>Reason</strong>: {2}</li>
                </ul>""".format(
            str(row[1]['ON STREET NAME']), str(row[1]['CROSS STREET NAME']),
            str(row[1]['CONTRIBUTING FACTOR VEHICLE 1']))
        iframe = folium.element.IFrame(html=accident_metadata, width=250, height=100)
        popup = folium.Popup(iframe, max_width=2650)
        folium.Marker(
                location = [row[1]['LATITUDE'], row[1]['LONGITUDE']],
                icon = folium.Icon(color='red', icon='asterisk'),
                popup=popup).add_to(collision_cluster)

# Create new cluster group for cyclist injuries
bike_cluster = folium.MarkerCluster().add_to(injury_group)
for row in accident_data[0:MAX_RECORDS].iterrows():
    # Only plot point if lat/long is available.
    if (not np.isnan(row[1]['LATITUDE']) and not np.isnan(row[1]['LONGITUDE']) and row[1]['NUMBER OF CYCLIST INJURED'] >= 1 or row[1]['NUMBER OF CYCLIST KILLED'] >= 1):
        accident_metadata = """
                <ul>
                    <li><strong>On street</strong>: {0}</li>
                    <li><strong>Cross street</strong>: {1}</li>
                    <li><strong>Cyclists Injured</strong>: {2}</li>
                    <li><strong>Cyclists Killed</strong>: {3}</li>
                </ul>""".format(
            str(row[1]['ON STREET NAME']), str(row[1]['CROSS STREET NAME']),
            str(row[1]['NUMBER OF CYCLIST INJURED']), str(row[1]['NUMBER OF CYCLIST KILLED']))
        iframe = folium.element.IFrame(html=accident_metadata, width=250, height=100)
        popup = folium.Popup(iframe, max_width=2650)
        folium.Marker(
                location = [row[1]['LATITUDE'], row[1]['LONGITUDE']],
                icon = folium.Icon(color='blue', icon='asterisk'),
                popup=popup).add_to(bike_cluster)
        
# Create new cluster group for pedestrian injuries
ped_cluster = folium.MarkerCluster().add_to(injury_group)
for row in accident_data[0:MAX_RECORDS].iterrows():
    # Only plot point if lat/long is available.
    if (not np.isnan(row[1]['LATITUDE']) and not np.isnan(row[1]['LONGITUDE']) and row[1]['NUMBER OF PEDESTRIANS INJURED'] >= 1 or row[1]['NUMBER OF PEDESTRIANS KILLED'] >= 1):
        accident_metadata = """
                <ul>
                    <li><strong>On street</strong>: {0}</li>
                    <li><strong>Cross street</strong>: {1}</li>
                    <li><strong>Pedestrians Injured</strong>: {2}</li>
                    <li><strong>Pedestrians Killed</strong>: {3}</li>
                </ul>""".format(
            str(row[1]['ON STREET NAME']), str(row[1]['CROSS STREET NAME']),
            str(row[1]['NUMBER OF PEDESTRIANS INJURED']), str(row[1]['NUMBER OF PEDESTRIANS KILLED']))
        iframe = folium.element.IFrame(html=accident_metadata, width=250, height=100)
        popup = folium.Popup(iframe, max_width=2650)
        folium.Marker(
                location = [row[1]['LATITUDE'], row[1]['LONGITUDE']],
                icon = folium.Icon(color='green', icon='asterisk'),
                popup=popup).add_to(ped_cluster)

# Create new cluster group for automobile injuries
auto_cluster = folium.MarkerCluster().add_to(injury_group)
for row in accident_data[0:MAX_RECORDS].iterrows():
    # Only plot point if lat/long is available.
    if (not np.isnan(row[1]['LATITUDE']) and not np.isnan(row[1]['LONGITUDE']) and row[1]['NUMBER OF MOTORIST INJURED'] >= 1 or row[1]['NUMBER OF MOTORIST KILLED'] >= 1):
        accident_metadata = """
                <ul>
                    <li><strong>On street</strong>: {0}</li>
                    <li><strong>Cross street</strong>: {1}</li>
                    <li><strong>Motorists Injured</strong>: {2}</li>
                    <li><strong>Motorists Killed</strong>: {3}</li>
                </ul>""".format(
            str(row[1]['ON STREET NAME']), str(row[1]['CROSS STREET NAME']),
            str(row[1]['NUMBER OF MOTORIST INJURED']), str(row[1]['NUMBER OF MOTORIST KILLED']))
        iframe = folium.element.IFrame(html=accident_metadata, width=250, height=100)
        popup = folium.Popup(iframe, max_width=2650)
        folium.Marker(
                location = [row[1]['LATITUDE'], row[1]['LONGITUDE']],
                icon = folium.Icon(color='red', icon='asterisk'),
                popup=popup).add_to(auto_cluster)
        
# layer names for items separately        
# collision_cluster.layer_name = 'Collisions'
# bike_cluster.layer_name = 'Cyclist Injuries'
# ped_cluster.layer_name = 'Pedestrian Injuries'


folium.LayerControl().add_to(map)
map


Out[3]:

In [4]:
# Save html version of map.
map.save('accidents_by_type_map.html')