1

Using plotly i want to plot choropleth map for Indian districts. I am able to do it for Indian states. The link for Indian geojson states is - https://gist.githubusercontent.com/jbrobst/56c13bbbf9d97d187fea01ca62ea5112/raw/e388c4cae20aa53cb5090210a42ebb9b765c0a36/india_states.geojson

And link for Indian geojson districts is https://www.kaggle.com/datasets/adityaradha007/indian-districts-geojson.

This is my df:

df = {
    'district': ['Thiruvananthapuram', 'Kasaragod', 'Malappuram', 'Pathanamthitta', 'Wayanad', 'Alappuzha', 'Kozhikode',
                 'Kollam', 'Thrissur', 'Palakkad', 'Kannur', 'Kottayam', 'Ernakulam', 'Idukki'],
    'registeredUsers': [989791, 294943, 871127, 271165, 234308, 534116, 887215, 623472, 768604, 620428, 640842, 504349,
                        1454447, 277492],
    'appOpens': [5574116, 5220451, 9688261, 4036616, 6349929, 2971951, 8824744, 4995465, 5764628, 9057055, 8394165,
                 4454903, 8812130, 9903479]
}

below code works for state:

fig = px.choropleth(
    df,
    geojson="https://gist.githubusercontent.com/jbrobst/56c13bbbf9d97d187fea01ca62ea5112/raw/e388c4cae20aa53cb5090210a42ebb9b765c0a36/india_states.geojson",
    featureidkey='properties.ST_NM',
    locations='state',
    color='registeredUsers',
    color_continuous_scale="viridis_r"
    #scope="asia",
    #range_color = (0, 12),
    #color_continuous_scale='Blues'
)

fig.update_geos(fitbounds="locations", visible=False)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) #scale map
fig.show()

below code does not work for districts:

fig = px.choropleth(
    df,
    geojson="/Users/adityaradhakrishnan/Desktop/output.geojson",
    featureidkey='properties.dtname',
    locations='district',
    color='registeredUsers',
    color_continuous_scale="viridis_r"
    #scope="asia",
    #range_color = (0, 12),
    #color_continuous_scale='Blues'
)

fig.update_geos(fitbounds="locations", visible=False)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) #scale map
fig.show()

but using matplotlib im able to plot(please not i am trying to plot only partial map here):

import matplotlib.pyplot as plt
import geopandas as gpd

# Read GeoJSON data into a GeoDataFrame
gdf = gpd.read_file("/Users/adityaradhakrishnan/Desktop/output.geojson")

# Merge the GeoDataFrame with your DataFrame based on the 'district' column
merged = gdf.merge(df, left_on='dtname', right_on='district')

# Plot the choropleth map
fig, ax = plt.subplots(figsize=(10, 8))
merged.plot(column='registeredUsers', cmap='viridis_r', linewidth=0.8, ax=ax, edgecolor='0.8', legend=True)

# Set plot title and axis labels
ax.set_title('Registered Users by District')
ax.set_xlabel('Longitude')
ax.set_ylabel('Latitude')

# Show the plot
plt.show()

Aditya
  • 21
  • 3

1 Answers1

0

Tried your code out. On Firefox I got a clear error in the console:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at file:///my-path/output.geojson. (Reason: CORS request not http).

MDN says this:

Local files from the same directory and subdirectories were historically treated as being from the same origin. This meant that a file and all its resources could be loaded from a local directory or subdirectory during testing, without triggering a CORS error.

Unfortunately this had security implications, as noted in this advisory: CVE-2019-11730. Many browsers, including Firefox and Chrome, now treat all local files as having opaque origins (by default). As a result, loading a local file with included local resources will now result in CORS errors.

Developers who need to perform local testing should now set up a local server. As all files are served from the same scheme and domain (localhost) they all have the same origin, and do not trigger cross-origin errors.

In this case we don't need to set up a local server. We can just read the local file, parse it and pass the result to geojson. After this the map displays.

With the data set you linked the map doesn't show all districts, I'm not sure why this is. I found another data set for Indian districts and that one seems to work (https://github.com/geohacker/india/blob/master/district/india_district.geojson):

import plotly.express as px
import pandas as pd
import geojson

with open('india_district.geojson') as f:
    gj = geojson.load(f)

df = {
    'district': ['Thiruvananthapuram', 'Kasaragod', 'Malappuram', 'Pathanamthitta', 'Wayanad', 'Alappuzha', 'Kozhikode', 'Kollam', 'Thrissur', 'Palakkad', 'Kannur', 'Kottayam', 'Ernakulam'],
    'registeredUsers': [989791, 294943, 871127, 271165, 234308, 534116, 887215, 623472, 768604, 620428, 640842, 504349, 1454447],
    'appOpens': [5574116, 5220451, 9688261, 4036616, 6349929, 2971951, 8824744, 4995465, 5764628, 9057055, 8394165, 4454903, 8812130]
}

fig = px.choropleth(
    df,
    geojson=gj,
    featureidkey='properties.NAME_2',
    locations='district',
    color='registeredUsers',
    color_continuous_scale="viridis_r"
)

fig.update_geos(fitbounds="locations", visible=False)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) #scale map
fig.show()

Parsing code taken from here.

5eb
  • 14,798
  • 5
  • 21
  • 65
  • This is plotting the map. but its not correct. Its just plotting one district Idukki. The rest is yellow in color. – Aditya Jun 11 '23 at 14:21
  • Not sure why that happens. Maybe the geojson data set is not good. I got it working with above approach with a different data set. Downloaded this one https://github.com/geohacker/india/blob/master/district/india_district.geojson. Instead of `'properties.dtname` use `'properties.NAME_2'`. – 5eb Jun 11 '23 at 15:46