I have been following this https://plotly.com/python/choropleth-maps/ tutorial to draw a choropleth map of Australian suburbs.
Using this https://github.com/tonywr71/GeoJson-Data/blob/master/australian-suburbs.geojson as the base geojson data, and then modifying it such that each feature has an 'id' property, which is the postcode for that feature. The final result looks like this: (available at https://github.com/meherGill/geojson_suburbs/blob/main/suburbsModified.geojson)
The corresponding dataframe for this is
and the code to draw the map is
import plotly.express as px
with open('./data/suburbsModified.geojson') as f:
jsondata = json.loads(f.read())
fig = px.choropleth(df2, geojson=jsondata, locations='Postal', color='Status', color_continuous_scale="Viridis")
fig.show()
But my figure looks like this, a map with nothing drawn on it.
Why is it not drawing a choropleth map of australian suburbs as defined in the geojson file
fundamentally your issues are the fact your geojson is problematic. Viewing on GitHub shows that modified geojson does not overlay Australia
original geojson shows other issues, a few of the features have no geometry. Have used geopandas to filter this out
have synthesized df2 from the geojson so that your code could be used
approach I would recommend is using source geojson and supplementing postal code in data frame
import requests
import pandas as pd
import numpy as np
import plotly.express as px
# original geojson
url = "https://raw.githubusercontent.com/tonywr71/GeoJson-Data/master/australian-suburbs.geojson"
# user's geojson
url = "https://raw.githubusercontent.com/meherGill/geojson_suburbs/main/suburbsModified.geojson"
fix = True
# get geojson
req = requests.get(url)
jsondata = req.json()
# well there is some invalid geomtry, exclude using geopandas
if fix:
gdf = gpd.GeoDataFrame.from_features(jsondata).set_index(
pd.json_normalize(jsondata["features"])["id"]
)
jsondata = gdf.loc[~gdf.geometry.isna()].__geo_interface__
# syntesize data frame
df2 = pd.DataFrame({"Postal": pd.json_normalize(req.json()["features"])["id"]}).assign(
Status=lambda d: np.random.randint(1, 400, len(d))
)
fig = px.choropleth(
df2,
geojson=jsondata,
locations="Postal",
color="Status",
color_continuous_scale="Viridis",
)
fig.show()
Related
Currently trying to learn cloropleth - fairly a noob with this.
Problem:
I'm currently using a Michigan Counties GeoJSON file and am trying to draw a map of the state showcasing the percentage of people that opted for John. In return though, I only get an empty colorless map of the US with a legend on the side. Like so:
Full dataset:
https://pastebin.com/x52E0Wii
My GeoJSON file can be found here: https://gis-michigan.opendata.arcgis.com/datasets/67a8ff23b5f54f15b7133b8c30981441/explore?location=44.847247%2C-86.594000%2C7.73
The code I'm using:
fig = px.choropleth(statistical_data,
locations = 'NAME',
locationmode = 'ISO-3',
geojson = michigan_counties,
color = '%John',
featureidkey = 'properties.NAME')
fig.show()
I was expecting a focused map of Michigan counties color coded with percentage of people who opted for John
The association between user data and geojosn is incorrect. In your data example, Maker, not fips, is the county name, so associate the name with the geojson property. Also, you do not need to set the location mode in this case. Since you presented 3 user data, the attached image shows only 3 regions. Also the geojosn data, but I could not get it correctly, so I used geosjon in the reference. Please make sure that the geojson property used has a name field.
from urllib.request import urlopen
import json
with urlopen('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json') as response:
counties = json.load(response)
import plotly.express as px
fig = px.choropleth(statistical_data,
locations = 'NAME',
geojson = counties,
color = '%John',
featureidkey = 'properties.NAME',
scope='usa')
fig.update_geos(fitbounds="locations", visible=False)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()
For a project I need to draw a choropleth map of Belgium and it's provinces.
When I draw the map I get this as a result.
I use the following python code to draw the map:
import plotly.express as px
import json
import pandas as pd
df = pd.read_csv("data/resulted_data/kmeans/CLUSTER_PROVINCES.csv")
with open('geojson.json') as file:
be = json.load(file)
fig = px.choropleth(df, geojson=be, locations="PROVINCE", featureidkey="properties.NameDUT", projection="mercator", color="CLUSTER", hover_data=["PROVINCE", "INFECTION_RATE", "HOSPITALISATION_RATE", "TEST_POS_PERCENTAGE", "CLUSTER"])
fig.update_geos(fitbounds="locations")
fig.show()
The geojson file I use works on geojson.io. The result on geojson.io is the following:
The used geojson file can be found here: https://raw.githubusercontent.com/mathiasleroy/Belgium-Geographic-Data/master/dist/polygons/geojson/Belgium.provinces.WGS84.geojson.
The only thing I changed in the geojson file is the value of the Dutch names for the provinces to match the names in my dataset.
I have no idea why it plots the province of Antwerp right but then covers the background with the same color.
The problem is that the geojson file is badly wound.
A solution to the problem can be found here: Solution
I just get started with data visualization and now I want to create a choropleth map show the number of soccer play in Premiere League.
I use python 3.8.5 and have a dataset in a CSV file. I try to create a choropleth map using plotly. After that, I created a choropleth, but my problem is the map didn't show any color, it only showed the earth form.
The code is here: https://github.com/quockhanhcao/Question
import json
import pandas as pd
import plotly.express as px
country = json.load(open("countries.geojson", "r"))
df = pd.read_csv('forward_country.csv')
country_code_map = {}
#map the code in geojson file of each country in csv file
for feature in country['features']:
feature['code'] = feature['properties']['ISO_A3']
country_code_map[feature['properties']['ADMIN']] = feature['code']
df['code'] = df['Country'].apply(lambda x: country_code_map[x])
fig = px.choropleth(df, locations='code', geojson=country, color = 'Number')
fig.show()
We need to link the country abbreviation name to GeoJson's ISO_A3.
from urllib.request import urlopen
import json
import pandas as pd
import plotly.express as px
with urlopen('https://raw.githubusercontent.com/quockhanhcao/Question/main/countries.geojson') as response:
country = json.load(response)
# country = json.load(open("./data/countries.geojson", "r"))
df = pd.read_csv('./data/forward_country.csv')
country_code_map = {}
#map the code in geojson file of each country in csv file
for feature in country['features']:
feature['code'] = feature['properties']['ISO_A3']
country_code_map[feature['properties']['ADMIN']] = feature['code']
df['code'] = df['Country'].apply(lambda x: country_code_map[x])
fig = px.choropleth(df, geojson=country,
locations='code',
featureidkey="properties.ISO_A3",
color='Number')
fig.show()
I have recently been looking into creating choropleth maps on plotly using Python. I was able to do this using a GeoJSON file I found on the internet (https://emilyshackleton1.carto.com/tables/uk_regions_map/public)
However I then went on the ONS GeoPortal and downloaded some GeoJSON files,
I then tried to create a choropleth map in the exact same manner, and it wouldn't work
Code:
import plotly.express as px
import pandas as pd
from urllib.request import urlopen
import json
with urlopen('https://opendata.arcgis.com/datasets/92ebeaf3caa8458ea467ec164baeefa4_0.geojson') as response:
ons2 = json.load(response)
area={}
for feature in ons2["features"]:
feature['id'] = feature["properties"]["objectid"]
area[feature["properties"]["ctry19nm"]] = feature["id"]
df3 = pd.DataFrame((['Wales',6.7],
['Scotland',4.6],
['England',4.7],
['Northern Ireland',4.1],
),columns='fips B'.split())
df3["id"]=df3["fips"].apply(lambda x: area[x])
fig = px.choropleth(df3, locations="id", geojson=ons2["features"][1], color="B", scope = "europe", hover_name="fips")
fig.update_geos(fitbounds="locations", visible=False)
fig.show()
For some reason it is coloring the whole space and only Northern Ireland is showing.
The weird thing is if I hover over this map it still comes up with Scotland, England and Wales where they should be
This has been driving me crazy, would appreciate any help :)
I tested your code with other GeoJSON files and it worked. Also your GeoJSON file does not have any errors, so there is likely a bug in the plotly library.
As an alternative, I can recommend to use the px.choropleth_mapbox() function which is quite similar to px.choropleth().
import plotly.express as px
import pandas as pd
from urllib.request import urlopen
import json
with urlopen('https://opendata.arcgis.com/datasets/92ebeaf3caa8458ea467ec164baeefa4_0.geojson') as response:
ons2 = json.load(response)
area={}
for feature in ons2["features"]:
feature['id'] = feature["properties"]["objectid"]
area[feature["properties"]["ctry19nm"]] = feature["id"]
df3 = pd.DataFrame((['Wales',6.7],
['Scotland',4.6],
['England',4.7],
['Northern Ireland',4.1],
),columns='fips B'.split())
df3["id"]=df3["fips"].apply(lambda x: area[x])
fig = px.choropleth_mapbox(df3, locations="id", featureidkey="properties.objectid", geojson=ons2, color="B", hover_name="fips", mapbox_style="white-bg", zoom=4, center = {"lat": 55, "lon": 0})
fig.show()
I am working on Kaggle Global Terrorism Database (https://www.kaggle.com/START-UMD/gtd/download) and I am trying to use geopandas for visualization.
I am also using countries dataset (http://www.naturalearthdata.com/downloads/110m-cultural-vectors/110m-admin-0-countries/)
import seaborn as sns
import geopandas as gpd
import matplotlib.pyplot as plt
sns.set(style = "ticks", context = "poster")
from shapely.geometry import Point
countries = gpd.read_file("C:/Users/petr7/Desktop/ne_110m_admin_0_countries/")
countries = countries[(countries['NAME'] != "Antarctica")]
countries.plot(figsize = (15, 15))
using code above I can easily plot entire Europe,
after that I import kaggle terrorist dataset and define it as geopandas dataframe
DF = pd.read_csv("C:/Users/petr7/Desktop/gtd/globalterrorismdb_0718dist.csv", encoding='latin1')
crs = {"init": "epsg:4326"}
geometry = [Point(xy) for xy in zip ( DF["longitude"], DF["latitude"])]
geo_DF = gpd.GeoDataFrame(DF, geometry = geometry)
geo_DF.head()
Until this point everything is working and dataset can be inspect
NOW when I try to plot it it return nonsense plot:
geo_DF.plot()
I am prety new to geopandas so I wanted to ask what I am missing and also how would you plot entire europe map (countries.plot) and above that terrorist attacks?
PICTURE HERE
There is an error in the data. DF["longitude"].min() gives -86185896.0.
DF.loc[DF["longitude"] == DF["longitude"].min()]
As you can see if you run the snippet above, row with the error is 17658.
It seems to be missing comma. If you do
DF.at[17658, 'longitude'] = -86.185896
before generating geometry, it will work. Or you can drop the row if you are not sure what is exactly wrong with the data.