Cleaning up a Choropleth Map - python

Good afternoon Stack!!
Pretty straight forward question here. I built a Choropleth to show the density of the soldiers I have where in my army reserve unit. The problem I have is that the map results come back in pretty much monochrome. its not the green scale I used in fill. Am I dumb and missed something??
For obvious reasons I'm not going to share what the map looks like now so any advice is warmly welcomed.
import folium
import pandas as pd
import json
from folium import plugins
##Create data frame
df = pd.read_csv('soldier data.csv')
numSoldiersSeries = df.groupby('Zip').count()
soldiersByZip = pd.DataFrame()
soldiersByZip['ZCTA5CE10'] = [str(i) for i in numSoldiersSeries.index]
soldiersByZip['numSoldiers'] = numSoldiersSeries.values
#Create Zipcode Overlay
with open('pa.geojson', 'r') as f:
pa = json.load(f)
##Create starting map
neMap = folium.Map(location=[40.767937,-73.982155], zoom_start=7)
##Create color overlay
folium.Choropleth(geo_data = pa, data=soldiersByZip,
columns=['ZCTA5CE10', 'numSoldiers'],
key_on='feature.properties.ZCTA5CE10',
fill_color='YlGn',
fill_opacity=.2,
line_opacity=1).add_to(neMap)
neMap.save('nemap.html')

Related

Folium Color Issues

I'm working with Folium for the first time, and attempting to make a Choropleth map of housing values in North Carolina using Zillow data as the source. I've been running into lots of issues along the way, and right now I'm a bit stuck on how to add in colors to the map; if the property value is >100k make it green, and slowing increasing the gradient to orange if it's <850k.
At the moment the map does generate the zip code data fine, but all of the polygons are a black-grey color. It's also not showing a color key or map name, and I have a feeling some of my earlier code could be off.
import folium
import pandas as pd
import requests
import os
working_directory = os.getcwd()
print(working_directory)
path = working_directory + '/Desktop/NCHomes.csv'
df = pd.read_csv(path)
df.head()
df['Homes'].min(), df['Homes'].max()
INDICATOR = 'North Carolina Home Values by Zip Code'
data = df[df['RegionName'] == INDICATOR]
max_value = data['Homes'].max()
data = data[data['Homes'] == max_value]
data.head()
geojson_url = 'https://raw.githubusercontent.com/OpenDataDE/State-zip-code-GeoJSON/master/nc_north_carolina_zip_codes_geo.min.json'
response = requests.get(geojson_url)
geojson = response.json()
geojson
geojson['features'][0]
map_data = data[['RegionName', 'Homes']]
map_data.head()
M = folium.Map(location=[20, 10], zoom_start=2)
folium.Choropleth(
geo_data=geojson,
data=map_data,
columns=['RegionName', 'Homes'],
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.2,
legend_name=INDICATOR
).add_to(M)
M
You can specify the threshold_scale parameter as follows:
folium.Choropleth(
geo_data=geojson,
data=map_data,
columns=['RegionName', 'Homes'],
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.2,
threshold_scale=[100000, 850000],
legend_name=INDICATOR
).add_to(M)

Folium chloropleth map only showing grey - help to troubleshoot

I having trouble getting some air pollution data to show different colors in a chloropleth map using folium. Please let me know where my code may be throwing an error. I think it is the key_on parameter but need help.
This is how my map turns out.
enter image description here
What I would like is for the mean concentration of the air pollution data to show up on the map but the map is still greyed out.
Here are the files I used:
Geojson file - Used "download zip" in upper right of this website https://gist.github.com/miguelpaz/edbc79fc55447ae736704654b3b2ef90#file-uhf42-geojson
Data file - Exported data from here https://a816-dohbesp.nyc.gov/IndicatorPublic/VisualizationData.aspx?id=2023,719b87,122,Summarize
Here is my code:
import geopandas as gpd
import folium
#clean pollution data
pm_df1 = pd.read_csv('/work/Fine Particulate Matter (PM2.5).csv',header = 5, usecols = ['GeoTypeName', 'Borough','Geography', 'Geography ID','Mean (mcg per cubic meter)'], nrows = 140)
#limit dataframe to rows with neighborhood (UHF 42) that matches geojson file
pm_df2 = pm_df1[(pm_df1['GeoTypeName'] == 'Neighborhood (UHF 42)')]
pm_df2
#clean geojson file
uhf_df2 = gpd.read_file('/work/uhf42.geojson', driver='GeoJSON')
uhf_df2.head()
#drop row 1 that has no geography
uhf_df3 = uhf_df2.iloc[1:]
uhf_df3.head()
## create a map
pm_testmap = folium.Map(location=[40.65639,-73.97379], tiles = "cartodbpositron", zoom_start=10)
# generate choropleth map
pm_testmap.choropleth(
geo_data=uhf_df3,
data=pm_df2,
columns=['Geography', 'Mean (mcg per cubic meter)'],
key_on='feature.properties.uhf_neigh', #think this is where I mess up.
fill_color='BuPu',
fill_opacity=0.2,
line_opacity=0.7,
legend_name='Average dust concentration',
smooth_factor=0)
# display map
pm_testmap
The problem with key_on is right as you think.
Both data have the name of UHF written on them, but in a completely different form.
In order to link these two, the data must first be preprocessed.
I don't know your data.
It would be nice if you could df.head() the two data to show them, but I'll explain based on the data I checked through the link you provided.
In your geojson file, uhf_neigh simply says Northeast Bronx. However, your PM data appears to have the region listed as Bronx: Northeast Bronx. The following process seems to be necessary to unify your local name before plotting map.
uhf_df2['UHF_NEIGH'] = uhf_df2['BOROUGH']+ ': ' + uhf_df2['UHF_NEIGH']
I tried to run it with your data and code, but it was not even displaying the map. There should be no problem in your code because you have associated the place name in the data frame with the place name in geojson. I gave up on the string association and changed the association to a place name code association, and the map was displayed. The provided csv file failed to load, so I deleted the unnecessary lines and loaded it. Also, I read the file as a json file instead of geopandas.
import pandas as pd
import geopandas as gpd
import json
import folium
pm_df1 = pd.read_csv('./data/test_20211221.csv')
pm_df1 = pm_df1[['GeoTypeName', 'Borough', 'Geography', 'Geography ID', 'Mean (mcg per cubic meter)']]
pm_df2 = pm_df1[(pm_df1['GeoTypeName'] == 'Neighborhood (UHF 42)')]
with open('./data/uhf42.geojson') as f:
uhf_df3 = json.load(f)
pm_testmap = folium.Map(location=[40.65639,-73.97379], tiles = "cartodbpositron", zoom_start=10)
# generate choropleth map
pm_testmap.choropleth(
geo_data=uhf_df3,
data=pm_df2,
columns=['Geography ID', 'Mean (mcg per cubic meter)'],
key_on='feature.properties.uhfcode', #think this is where I mess up.
fill_color='BuPu',
fill_opacity=0.2,
line_opacity=0.7,
legend_name='Average dust concentration',
smooth_factor=0)
# display map
pm_testmap

My Choropleth Map gets stuck loading and never finishes?

Relatively new here and new to Python in general, but trying to work with Plotly Express to create myself a Choropleth map that allows me to color-code custom data on countries. However, I'm having trouble actually loading the map up. I've been able to load the native Choropleth map with none of my data, but when I link my own geojson data set to the function it gets stuck loading on line 30. I haven't quite been able to figure out why, since it just gets stuck and gives me nothing else to troubleshoot with.
Any help is greatly appreciated!
import random
from token_file import token
import pandas as pd
import plotly.express as px
import json
with open('documents/countries.geojson') as f:
data = json.load(f)
countries = {}
for features in data["features"]:
if features["properties"]["ISO_A3"] != "-99":
name = features["properties"]["ADMIN"]
iso = features["properties"]["ISO_A3"]
geo = features["geometry"]
val = random.randint(0, 100)
values = pd.Series([name, iso, val], index=["Name", "ISO", "Val"])
countries[name] = values
else:
continue
countries = pd.DataFrame(countries)
countries = countries.transpose()
print(countries)
px.set_mapbox_access_token(token)
map = px.choropleth_mapbox(countries, locations="ISO", zoom=1, hover_name="Name", hover_data=["ISO"],
color="Val", color_continuous_scale="Viridis", mapbox_style="carto-positron")
map.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
map.show()

Creating a UK Heatmap

I have a data frame for UK data that looks something like this:
longitude latitude region priority
51.307733 -0.75708898 South East High
51.527477 -0.20646542 London Medium
51.725135 0.4747223 East of England Low
This dataframe is several thousand rows long. I want a heatmap of the UK broken down by the regions and colour intensity to be dependent on the priority in each region.
I would like to know the best way to turn this into a heatmap of the UK. I have tried geoPandas and Plotly but I have no functioning knowledge of these. Are these the best way to do it or is there a tool out there that you can simply upload your data to and it will plot it for you? Thanks!
For this kind of job i use to go with folium, which is great to work with maps,
But for the heatMap you have to have your "priority" column as float!
import folium
from folium import plugins
from folium.plugins import HeatMap
my_map = folium.Map(location=[51.5074, 0.1278],
zoom_start = 13) # for UK
your_dataframe['latitude'] = your_dataframe['latitude'].astype(float)
your_dataframe['longitude'] = your_dataframe['longitude'].astype(float)
your_dataframe['priority'] = your_dataframe['priority'].astype(float)
heat_df = your_dataframe[['latitude', 'longitude','priority']]
heat_df = heat_df.dropna(axis=0, subset=['latitude','longitude','priority'])
# List comprehension to make out list of lists
heat_data = [[row['latitude'],row['longitude'],row['priority']] for index, row in heat_df.iterrows()]
my_map.add_children(plugins.HeatMap(heat_data))
my_map.save('map.html')
and then you have to open map.html with yout browser

Folium Choropleth map marker is not working

I'm trying to follow the blog post from Domino lab, Creating interactive crime maps with Folium. And I found that the code base is too old to run the Folium's Choropleth map marker. Although older version on Domino platform seems working (2015), the latest Ipython notebook doesn't work. So I'm guessing Folium changed something on markers? I tried to find the update but I can't find it. Are anyone familiar with this library? If so please give me advices.
My code below:
from IPython.display import HTML
def display(m, height=500):
"""Takes a folium instance and embed HTML."""
m._build_map()
srcdoc = m.HTML.replace('"', '"')
embed = HTML('<iframe srcdoc="{0}" '
'style="width: 100%; height: {1}px; '
'border: none"></iframe>'.format(srcdoc, height))
return embed
import folium
import pandas as pd
SF_COORDINATES = (37.76, -122.45)
crimedata = pd.read_csv('data/SFPD_Incidents_-_Current_Year__2015_.csv')
#for speed purposes
MAX_RECORDS = 1000
#create empty map zoomed in on San Francisco
map = folium.Map(location=SF_COORDINATES, zoom_start=12)
#add a marker for every record in the filtered data, use a clustered view
for each in crimedata[0:MAX_RECORDS].iterrows():
map.simple_marker(
location = [each[1]['Y'],each[1]['X']],
clustered_marker = True)
display(map)
#definition of the boundaries in the map
district_geo = r'data/sfpddistricts.json'
#calculating total number of incidents per district
crimedata2 = pd.DataFrame(crimedata['PdDistrict'].value_counts().astype(float))
crimedata2.to_json('data/crimeagg.json')
crimedata2 = crimedata2.reset_index()
crimedata2.columns = ['District', 'Number']
#creation of the choropleth
map1 = folium.Map(location=SF_COORDINATES, zoom_start=12)
map1.geo_json(geo_path = district_geo,
data_out = 'data/crimeagg.json',
data = crimedata2,
columns = ['District', 'Number'],
key_on = 'feature.properties.DISTRICT',
fill_color = 'YlOrRd',
fill_opacity = 0.7,
line_opacity = 0.2,
legend_name = 'Number of incidents per district')
display(map1)
Not sure if you mean markers (popups) or the choropleth method itself isn't working?
The map1.geo_json() method is deprecated (see here).
Instead, try map1.choropleth(geo_path = district_geo,
data_out = 'data/crimeagg.json',
data = crimedata2,
columns = ['District', 'Number'],
key_on = 'feature.properties.DISTRICT',
fill_color = 'YlOrRd',
fill_opacity = 0.7,
line_opacity = 0.2,
legend_name = 'Number of incidents per district')
The map.choropleth method worked for me, but don't know if they fixed the popup issue for choropleth maps. Hope this helps!
The mapObject.choropleth method is being depricated.
folium.GeoJson is the suggested method as per this github issue: https://github.com/python-visualization/folium/issues/589
A comment in that issue links to this example, which shows how to build the choropleth:
http://nbviewer.jupyter.org/github/python-visualization/folium/blob/master/examples/GeoJSON_and_choropleth.ipynb?flush_cache=true
TLDR
replace geo_json with GeoJson
and for the args like fill_color, use fillColor: <hex_color> in the style_function dictionary kwarg.

Categories