如何用Plotly go.Choroplethmapbox()绘制.shp文件?



我需要使用自定义SHP文件在Plotly map上绘制Choropleth图。

SHP文件用于获取边界信息。我将其转换为geojson并将其提供给Plotly,但我得到的只是一个没有错误消息的空基图。

这是我尝试的:

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()

问题:如何用Plotly go.Choroplethmapbox()从一个SHP文件绘制一个choropleth ?

  • 你错过了一个非常重要的步骤,考虑CRS投影https://geopandas.org/docs/user_guide/projections.html
  • 使用geodf = geodf.to_crs("WGS84")
  • 解决此问题
  • 另外,使用https://plotly.com/python/mapbox-county-choropleth/#using-geopandas-data-frames生成这个mapbox要简单得多

绘制图形对象

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),
)

情节表达

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

最新更新