Geom
Geom

Reputation: 1546

How to plot a .SHP file with Plotly go.Choroplethmapbox()?

I need to plot a Choropleth graph on a Plotly map using a custom SHP file.

SHP file is used to get the boundary information. I convert it to geojson and feed it to Plotly but all i get is an empty base-map with no error messages.

Here is what i tried:

import json
import random
import pandas as pd
import geopandas as gpd
import plotly.graph_objects as go

# Create GeoDataFrame for SHP file
geodf = gpd.read_file('data/postal-areas-2021/PKS_postinumeroalueet_2021_shp.shp')
# Save as geojson
geodf.to_file("data.geojson", encoding='utf-8', driver = "GeoJSON")
# Open the file
with open("data.geojson", encoding='utf-8') as geofile:
    counties = json.load(geofile)

# Create a new Dataframe for supplying z values(colors) to Choropleth.
df = pd.DataFrame()

# Create lists to store the values
postal_code = []
rand = []
# Using Posno(Postal code) as ID and generateing random integers from 1-100 as a color value
for i,v in enumerate(counties['features']):
    postal_code.append(counties['features'][i]['properties']['Posno'])
    rand.append(random.randint(1,100))

# Adding the columns to the dataframe
df['Posno'] = postal_code
df['rand'] = rand

# Creating the figure and assigning the values
fig = go.Figure(go.Choroplethmapbox(geojson=counties, locations=df['Posno'], z=df['rand'],
                                    colorscale="Viridis", zmin=0, zmax=12, marker_line_width=5))

fig.update_layout(mapbox_style="open-street-map",
                        height = 1000,
                        autosize=True,
                        margin={"r":0,"t":0,"l":0,"b":0},
                        paper_bgcolor='#303030',
                        plot_bgcolor='#303030',
                        mapbox=dict(center=dict(lat=60.1699, lon=24.9384),zoom=11),
                        )
fig.show()

Question: How to plot a choropleth from an SHP file with Plotly go.Choroplethmapbox()?

Upvotes: 0

Views: 6787

Answers (1)

Rob Raymond
Rob Raymond

Reputation: 31226

plotly graph objects

import requests
from pathlib import Path
from zipfile import ZipFile
import geopandas as gpd
import numpy as np
import plotly.graph_objects as go
import json

# get the shape file...
url = "https://avoidatastr.blob.core.windows.net/avoindata/AvoinData/9_Kartat/PKS%20postinumeroalueet/Shp/PKS_postinumeroalueet_2021_shp.zip"

fn = Path.cwd().joinpath(url.split("/")[-1])
if not fn.exists():
    r = requests.get(url, stream=True)
    with open(fn, "wb") as f:
        for chunk in r.raw.stream(1024, decode_content=False):
            if chunk:
                f.write(chunk)

zfile = ZipFile(fn)
zfile.extractall()

# open it...
geodf = gpd.read_file(list(Path.cwd().glob("PKS*.shp"))[0])
geodf["rand"] = np.random.randint(1, 100, len(geodf))

# shape file is a different CRS,  change to lon/lat GPS co-ordinates
geodf = geodf.to_crs("WGS84").set_index("Posno")


fig = go.Figure(go.Choroplethmapbox(geojson=json.loads(geodf.to_json()), 
                                    locations=geodf.index, z=geodf['rand'],
                                    colorscale="Viridis", marker_line_width=.5))

fig.update_layout(mapbox_style="open-street-map",
                        height = 1000,
                        autosize=True,
                        margin={"r":0,"t":0,"l":0,"b":0},
                        paper_bgcolor='#303030',
                        plot_bgcolor='#303030',
                        mapbox=dict(center=dict(lat=60.1699, lon=24.9384),zoom=9),
                        )

plotly express

import requests
from pathlib import Path
from zipfile import ZipFile
import geopandas as gpd
import numpy as np
import plotly.express as px

# get the shape file...
url = "https://avoidatastr.blob.core.windows.net/avoindata/AvoinData/9_Kartat/PKS%20postinumeroalueet/Shp/PKS_postinumeroalueet_2021_shp.zip"

fn = Path.cwd().joinpath(url.split("/")[-1])
if not fn.exists():
    r = requests.get(url, stream=True)
    with open(fn, "wb") as f:
        for chunk in r.raw.stream(1024, decode_content=False):
            if chunk:
                f.write(chunk)

zfile = ZipFile(fn)
zfile.extractall()

# open it...
geodf = gpd.read_file(list(Path.cwd().glob("PKS*.shp"))[0])
geodf["rand"] = np.random.randint(1, 100, len(geodf))

# shape file is a different CRS,  change to lon/lat GPS co-ordinates
geodf = geodf.to_crs("WGS84")

fig = px.choropleth_mapbox(
    geodf.set_index("Posno"),
    geojson=geodf.geometry,
    locations=geodf.index,
    color="rand",
    center=dict(lat=60.1699, lon=24.9384),
    mapbox_style="open-street-map",
    zoom=9,
)

fig.update_layout(
    height=1000,
    autosize=True,
    margin={"r": 0, "t": 0, "l": 0, "b": 0},
    paper_bgcolor="#303030",
    plot_bgcolor="#303030",
)

fig

Upvotes: 1

Related Questions