Police Crime Statistics around a postcode

So given a postcode, you can use the police API to list crimes in a 1 mile radius. It’s interesting to list the places the crimes are – if its your area. But it’s instructive to have them graphed over time also.

Using the python libary geopy we can use translate the postcode to coordinates:

''' Obtaining latitude/longitude from postcode '''
postcode='AB1 2DE'
from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="myagent_postcode")
location = geolocator.geocode(postcode)
lng = location.raw['lon']
lat = location.raw['lat']

The police api has get_crimes_location to return a list of crimes for the latest published month.

  crimlist = api.get_crimes_point(lat,lng)

And you can go back years to plot them by specifying previous dates.

for n in range(18):
    date_chunk = date_list[n]
    crimlist = api.get_crimes_point(lat,lng,date_chunk)
    for crime in crimlist:
       ...

Anyway, here’s some code, useful for me as a reminder, maybe inspiring for others.

#!/usr/bin/env python3
import sys
from police_api import PoliceAPI
from police_api.neighbourhoods import Neighbourhood
from police_api.forces import Force
import pprint
import geocoder
import plotly.express as px
import pandas
from IPython.display import display
from tabulate import tabulate

pp = pprint.PrettyPrinter(indent=4)
api = PoliceAPI()

''' Obtaining latitude/longitude from postcode '''
postcode='AB1 2CD'
from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="myunique_postcode")
location = geolocator.geocode(postcode)
lng = location.raw['lon']
lat = location.raw['lat']
address = location.address
place = postcode + "/" + lng + "/" + lat

''' Display a nice table of recent crimes '''
import csv
with open('myhouse.csv', mode='w') as myhouse_file:
  myhouse_writer = csv.writer(myhouse_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
  myhouse_writer.writerow(['Date', 'Category', 'Location','Outcome','Longitude', 'Latitude'])
  crimlist = api.get_crimes_point(lat,lng)
  for crime in crimlist:
      myhouse_writer.writerow([crime.month, str(crime.category).replace("<CrimeCategory>",""), crime.location.name, crime.outcome_status,crime.location.longitude, crime.location.latitude])
df = pandas.read_csv("myhouse.csv")
df = df.drop(['Outcome'], axis=1)
df = df.drop(['Longitude'], axis=1)
df = df.drop(['Latitude'], axis=1)
print(place)
print(tabulate(df, headers = 'keys', tablefmt = 'psql'))

''' This is a graph of 18 months of the same data '''
import csv
with open('myhouse.csv', mode='w') as myhouse_file:
  myhouse_writer = csv.writer(myhouse_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
  date_list = api.get_dates()
  myhouse_writer.writerow(['Date', 'Category', 'Location','Outcome','Longitude', 'Latitude'])
  for n in range(18):
    date_chunk = date_list[n]
    crimlist = api.get_crimes_point(lat,lng,date_chunk)
    for crime in crimlist:
      myhouse_writer.writerow([crime.month, str(crime.category).replace("<CrimeCategory>",""), crime.location.name, crime.outcome_status,crime.location.longitude, crime.location.latitude])

df = pandas.read_csv("myhouse.csv")
df = df.groupby(['Date','Category'])['Category'].count()   .reset_index(name='Count')
df = df.sort_values(by=['Date', 'Category'])
fig =  px.line(df, x = 'Date', y = 'Count', title='Crime nr ' + place,  color='Category', hover_name = 'Category' )
fig.show()