#!/usr/bin/env python # coding: utf-8 #

FT Crusader Logo

#

Saint Paul, MN, Vacant Building Report; 12/15/19

#

By Abu Nayeem aka Frogtown Crusader

# ### Table of Contents # # * Intro # * [Data Exploration](#explore) # - [Distribution Plots](#dist) # - [Vacancy by District Council](#council) # - [Vacancy by Ward](#ward) # * Interactive Vacant Buildings Maps # - [Interactive Map: Saint Paul Vacant Building by Year](#spyear) # - [Interactive Map: Saint Paul Vacant Buildings by Dwelling Type](#spdwell) # - [Interactive Map: District 7/ Ward 1 Vacant Building by Dwelling Type](#spward1) # - [Interactive Crime Map with Vacant Building for Ward1](#crime) # * [Concluding Remarks](#conclude) # * [Running Code](#code) # ### Introduction # # On the city of Saint Paul Data Portal, there is information on the number of current vacant buildings in Saint Paul. You can download the data from [here](https://information.stpaul.gov/Buildings-Housing-Economic-Development/Vacant-Buildings-Dataset/fgbn-288b). If a building is occupied, then it will be removed for the list. Thus there will be more vacant houses within the last 2 to 3 years. The number of vacant properties can provide concern for a community but also an opportunity to revitalize an area. Classic example of urban blight is when many commercial fronts have closed down, which impacts development nearby. Vacant/abandoned properties, for better or for worse could provides a space space for illicit activities or it can provide housing for the homeless and downtrodden. # # With this report, I hope residents can find areas that need more resources (i.e. economic development and housing resources) and consider options in dealing with the looming housing. # #### Data # # This dataset contains all of the registered vacant buildings in the City, as well as their type, and Vacant Building Category. # In[32]: df.head(2) # #### Vacant Buildings by Year Plot # In[20]: plt.figure(figsize=(10,6)) sns.set_style("darkgrid") #white, white-grid, ticks sns.distplot(df['Year'], kde=False).set_title("Current Vacant Buildings by Year of Vacancy") # #### Vacant Buildings Types # In[4]: print(df['Dwelling'].value_counts().sort_index(level=1)) # ### Vacant Buildings Broken Down by District Council # In[21]: plt.figure(figsize=(10,6)) sns.distplot(df['District'], bins=17, vertical=True, kde=False).set_title("Current Vacant Buildings by District Council") # #### Vacant Dwellings Categories broken down by District # In[6]: barplot('District',12,9) # ### Vacant Buildings Broken Down by Ward # In[22]: plt.figure(figsize=(10,6)) sns.distplot(df['Ward'], bins=17, vertical=True, kde=False).set_title("Current Vacant Buildings by Ward Grid") # In[23]: plt.figure(figsize=(10,6)) barplot('Ward',7,7) # ### Interactive Saint Paul Vacant Buildings Map by Year Range # # **CLick on dots to get more information**; please zoom in # # **Legend: Vacant Year Range** # # - **Red:** Earlier than 2013 # - **Orange:** 2013 to 2015 # - **Brown:** 2016 # - **Blue:** 2017 # - **Green:** 2018 to present # In[24]: map_Vacancy_byYear() # ### Saint Paul Interactive Vacant Buildings by Dwelling Type # # # **Legend: Dwelling Type** # # - **Red:** Mixed Use # - **Orange:** Duplex # - **Brown:** Commercial # - **Blue:** Multi-Family # - **Green:** Single Family # # In[25]: map_Vacancy_TypeWard() # ### Interactive Vacant Buildings by Dwelling for Thomas-Dale-Frogtown Community # # **Legend: Dwelling Type** # # - **Red:** Mixed Use # - **Orange:** Duplex # - **Brown:** Commercial # - **Blue:** Multi-Family # - **Green:** Single Family # In[26]: map_Vacancy_TypeDistrict(7) # ### Interactive Vacant Buildings by Dwelling type Ward 1 # # **Legend: Dwelling Type** # # - **Red:** Mixed Use # - **Orange:** Duplex # - **Brown:** Commercial # - **Blue:** Multi-Family # - **Green:** Single Family # In[27]: map_Vacancy_TypeWard(1) # ### Interactive Hotspot Crime Map (from 2018 to Present) w/ Vacant Buildings for Ward 1 # # **Green:** Hotspot of at least 8 crimes or more # # **Orange:** Vacant buildings # # Note: The Crime Dataset is clean from Frogtown Map Project. This was my first attempt of combining to different datasets together in a map # In[28]: Map_Frogtown_VacantBuilding_Crime_Current() # ### Concluding Remarks # # There are some neighborhoods with clusters of vacant buildings. How should the community deal with this? how should revitalize look like? Is there a correlation between hotspots and vacant buildings? Feel free to explore. # ### Run Code # In[16]: df.iloc[:,4:] # In[1]: import pandas as pd from sodapy import Socrata #New Upload Method Get Information from Socrata API client = Socrata("information.stpaul.gov", None) results = client.get("fgbn-288b", limit=1000000) df = pd.DataFrame.from_records(results) # Remove meanigless first foour columns df=df.iloc[:,4:] #Set up columns and data types cols= ['Address','Census_Tract','District','Dwelling','Coordinates','Vacant_Building_Category','VacantDate', 'Ward'] df.columns= cols df = df.astype({"District": float, "Vacant_Building_Category": int, "Ward":float, "Census_Tract":float}) df.head(2) #df.columns= cols # In[2]: import pandas as pd import numpy as np import matplotlib.pyplot as plt from datetime import datetime import warnings warnings.filterwarnings('ignore') import seaborn as sns import scipy.stats as stats #used to get correlation coefficient import folium import pandas as pd from sodapy import Socrata #New Upload Method Get Information from Socrata API client = Socrata("information.stpaul.gov", None) results = client.get("fgbn-288b", limit=1000000) df = pd.DataFrame.from_records(results) # Remove meanigless first foour columns df=df.iloc[:,4:] #Set up columns and data types cols= ['Address','Census_Tract','District','Dwelling','Coordinates','Vacant_Building_Category','VacantDate', 'Ward'] df.columns= cols df = df.astype({"District": float, "Vacant_Building_Category": int, "Ward":float, "Census_Tract":float}) #load data #df = pd.read_csv('Data/Vacant_Buildings_-_Dataset.csv') #cols= ['Address','VacantDate','Dwelling','Vacant_Building_Category','Ward','District','Census_Tract','Coordinates','DistrictCouncilMap','CouncilWard','Gunk1','Gunk2'] #df.columns= cols # Get Coordinates by converting to string df['Coordinates'] = df['Coordinates'].astype('str') new=df['Coordinates'].str.split("', '", n = 1, expand = True) # get Latitude: lat=new[0].str.split(" '", n = 1, expand = True) df['Latitude']= pd.to_numeric(lat[1]) #Get Longtitude new= new[1].str.split("', '", n = 1, expand = True) long=new[0].str.split(" '", n = 1, expand = True) df['Longitude']= pd.to_numeric(long[1]) # Get Year and Date Variable df['Datetime']= pd.to_datetime(df['VacantDate']) df['Year']=df['Datetime'].dt.year df['Date']=pd.to_datetime(df['Datetime']).apply(lambda x: x.date()) df=df.query('Latitude != "NaN"') def map_Vacancy_byYear(): # generate a new map FG_map = folium.Map(location=[44.9608901, -93.1010336], zoom_start=12,tiles="OpenStreetMap") #setup Index =['Address','Date','Dwelling', 'Ward','District','Latitude','Longitude','Year'] B=df[Index] T=B.query('Year <= 2012') V=B.query('Year > 2012 and Year < 2016') N=B.query('Year == 2016') A=B.query('Year == 2017') D=B.query('Year in (2018,2019)') for index, row in T.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color= "#FF0000", #red popup=popup_text, fill=True).add_to(FG_map) for index, row in V.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color="#E37222", #orange popup=popup_text, fill=True).add_to(FG_map) for index, row in N.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color="#654321", #brown popup=popup_text, fill=True).add_to(FG_map) for index, row in A.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color="#0000ff", #blue popup=popup_text, fill=True).add_to(FG_map) for index, row in D.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color='#007849', #green popup=popup_text, fill=True).add_to(FG_map) return FG_map def map_Vacancy_TypeDistrict(Dis='All'): # generate a new map FG_map = folium.Map(location=[44.958326, -93.122926], zoom_start=14,tiles="OpenStreetMap") #setup Index =['Address','Date','Dwelling', 'Ward','District','Latitude','Longitude','Year'] if Dis=='All': B=df else: B=df[(df['District']==Dis)] B=B[Index] T=B.query('Dwelling == "Mixed Use"') V=B.query('Dwelling=="Duplex"') N=B.query('Dwelling == "Commerical"') A=B.query('Dwelling == "Multi-family Residential"') D=B.query('Dwelling == "Single Family Residential"') #Create Frogtown GeoMap FG_map = folium.Map(location=[44.958326, -93.122926], zoom_start=14,tiles="OpenStreetMap") for index, row in T.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color= "#FF0000", #red popup=popup_text, fill=True).add_to(FG_map) for index, row in V.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color="#E37222", #orange popup=popup_text, fill=True).add_to(FG_map) for index, row in N.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color="#654321", #brown popup=popup_text, fill=True).add_to(FG_map) for index, row in A.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color="#0000ff", #blue popup=popup_text, fill=True).add_to(FG_map) for index, row in D.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color='#007849', #green popup=popup_text, fill=True).add_to(FG_map) return FG_map def map_Vacancy_TypeWard(War='All'): # generate a new map FG_map = folium.Map(location=[44.958326, -93.122926], zoom_start=12,tiles="OpenStreetMap") #setup Index =['Address','Date','Dwelling', 'Ward','District','Latitude','Longitude','Year'] if War=='All': B=df else: B=df[(df['Ward']==War)] B=B[Index] T=B.query('Dwelling == "Mixed Use"') V=B.query('Dwelling=="Duplex"') N=B.query('Dwelling == "Commerical"') A=B.query('Dwelling == "Multi-family Residential"') D=B.query('Dwelling == "Single Family Residential"') #Create Frogtown GeoMap FG_map = folium.Map(location=[44.958326, -93.122926], zoom_start=14,tiles="OpenStreetMap") for index, row in T.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color= "#FF0000", #red popup=popup_text, fill=True).add_to(FG_map) for index, row in V.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color="#E37222", #orange popup=popup_text, fill=True).add_to(FG_map) for index, row in N.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color="#654321", #brown popup=popup_text, fill=True).add_to(FG_map) for index, row in A.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color="#0000ff", #blue popup=popup_text, fill=True).add_to(FG_map) for index, row in D.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color='#007849', #green popup=popup_text, fill=True).add_to(FG_map) return FG_map def barplot(Var1,fig1,fig2): plt.figure(figsize=(fig1,fig2)) A= df.groupby([Var1,'Dwelling']).count().sort_index(level=1) A=A.reset_index() A= A.query('Dwelling not in ("Mixed Use", "Multi-family Residential")') ax = sns.barplot(x="Date", y=Var1, hue="Dwelling", data=A, orient= 'h').set_title('Vacant Dwellings by {}'.format(Var1)) plt.xlabel('') return plt.show() # [Click to to scroll to table of content](#tc) # In[14]: #Upload Data fg = pd.read_csv('Data/FGCrime_Final.csv') #Set max limit for uptodate function Max= fg.loc[1,'Day_Max'] # Set a friendly Date variable fg['FDate']=fg['Month'].astype(str) + '/' + fg['Day'].astype(str) + '/' fgp= fg.query('Code in [9954]') # Specify proactive calls fgc= fg.query('Code not in [9954,9959]') #specify all crime related police visits fgc_Date= fgc[(fgc['DayYear'] <= Max)] #this specifies to date df def Map_Frogtown_VacantBuilding_Crime_Current(): # generate a new map FG_map = folium.Map(location=[44.958326, -93.122926], zoom_start=14,tiles="OpenStreetMap") #setup Bl= fgc[(fgc['Year'] > 2017)] Index =['Block','Latitude','Longitude', 'Count','Theft','Vandalism','Narcotics','Auto Theft','Burglary','Discharge'\ ,'Robbery','Domestic Assault','Violent','Arson'] BM=Bl.query('LateNight ==0') BM=BM[Index].groupby(['Block','Latitude','Longitude']).sum().reset_index() BM=BM.query('Count>7') # for each row in the data, add a cicle marker for index, row in BM.iterrows(): popup_text = "Year: 2018-19
Address: {}
total incidents: {}
Theft: {}
Vandalism: {}\
Narcotics: {}
Auto Theft: {}
Burglary: {}
Discharge: {}
Robbery: {}\
Domestic Assault: {}
Violent: {}
Arson: {}" popup_text = popup_text.format(row["Block"], row['Count'], row['Theft'], row['Vandalism'], row['Robbery'],\ row['Auto Theft'], row['Burglary'], row['Discharge'], row['Domestic Assault'],\ row['Domestic Assault'],row['Violent'],row['Arson']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=row['Count']/2, color="#007849", #green popup=popup_text, fill=True).add_to(FG_map) Index1 =['Address','Date','Dwelling', 'Ward','District','Latitude','Longitude','Year'] B=df[(df['Ward']==1)] B=B[Index1] for index, row in B.iterrows(): popup_text = "Address: {}
District: {}
Ward: {}
Date: {}
Dwelling:{}" popup_text = popup_text.format(row["Address"],row['District'],row['Ward'],row['Date'],row['Dwelling']) folium.CircleMarker(location=(row["Latitude"],row["Longitude"]), radius=5, color="#E37222", #orange popup=popup_text, fill=True).add_to(FG_map) return FG_map # In[ ]: