Я пытался визуализировать geo JSON в Plotly путем преобразования шейп-файлов из https://geoportal.statistics.gov.uk/datasets/local-authority-districts-december-2019-boundaries-uk-bfc.
Документы Python Plotly для plotly.graph_objects.Choroplethmapbox
упоминают, что в geo JSON поле id
необходимо для каждой функции. Я пробовал как создать искусственное id
, так и использовать поле plotly featurekeyid
, но ни один из них не работает. Когда я использую ключ id
, я проверял, что ключ id
находится в правильном месте, и пробовал использовать как int64, так и строку.
Иногда базовый слой mapbox отображает, но не полигоны, а в других случаях код запускается, а затем зависает.
Я также попытался уменьшить размер файла .shp с помощью различных алгоритмов maphaper, затем сохранил его в формате geo JSON и пропустил этап преобразования в Python из .shp в geo JSON, но снова но безрезультатно. Кроме того, изменение tolerance
в манипуляции shapely
, похоже, не влияет на результат.
Я ожидаю картографическую проекцию с базовым слоем mapbox с полигонами местных органов власти сверху и с заливкой. Ссылка ниже показывает многоугольники и была создана на mapshaper.org :
Полигоны округа местных властей
Токен доступа к моему mapbox действителен.
Это пример попытки визуализировать полигоны границ местных органов власти путем добавления поля id
и преобразования файла .shp в geo JSON, а затем создания трассировки:
import geopandas as gpd
from shapely.geometry import LineString, MultiLineString
import plotly.graph_objs as go
# load in shp files
lad_shp = gpd.read_file('zip://../../data/external/Local_Authority_Districts_(December_2019)_Boundaries_UK_BFC-shp.zip', encoding='utf-8')
# using empet code to convert .shp to geoJSON
def shapefile_to_geojson(gdf, index_list, tolerance=0.025):
# gdf - geopandas dataframe containing the geometry column and values to be mapped to a colorscale
# index_list - a sublist of list(gdf.index) or gdf.index for all data
# tolerance - float parameter to set the Polygon/MultiPolygon degree of simplification
# returns a geojson type dict
geo_names = list(gdf[f'lad19nm']) # name of authorities
geojson = {'type': 'FeatureCollection', 'features': []}
for index in index_list:
geo = gdf['geometry'][index].simplify(tolerance)
if isinstance(geo.boundary, LineString):
gtype = 'Polygon'
bcoords = np.dstack(geo.boundary.coords.xy).tolist()
elif isinstance(geo.boundary, MultiLineString):
gtype = 'MultiPolygon'
bcoords = []
for b in geo.boundary:
x, y = b.coords.xy
coords = np.dstack((x,y)).tolist()
bcoords.append(coords)
else: pass
feature = {'type': 'Feature',
'id' : index,
'properties': {'name': geo_names[index]},
'geometry': {'type': gtype,
'coordinates': bcoords},
}
geojson['features'].append(feature)
return geojson
geojsdata = shapefile_to_geojson(lad_shp, list(lad_shp.index))
# length to generate synthetic data for z attribute
L = len(geojsdata['features'])
# check id key is there
geojsdata['features'][0].keys()
>> dict_keys(['type', 'id', 'properties', 'geometry'])
# example of authroity name
geojsdata['features'][0]['properties']['name']
>> 'Hartlepool'
# check id
k=5
geojsdata['features'][k]['id']
>> '5'
trace = go.Choroplethmapbox(z=np.random.randint(10, 75, size=L), # synthetic data
locations=[geojsdata['features'][k]['id'] for k in range(L)],
colorscale='Viridis',
colorbar=dict(thickness=20, ticklen=3),
geojson=geojsdata,
text=regions,
marker_line_width=0.1, marker_opacity=0.7)
layout = go.Layout(title_text='UK LAD Choropleth Demo',
title_x=0.5,
width=750,
height=700,
mapbox=dict(center=dict(lat=54, lon=-2),
accesstoken=mapbox_access_token,
zoom=3))
fig=go.Figure(data=[trace], layout =layout)
fig.show()
geo JSON вывод из приведенной выше функции shapefile_to_geojson
можно найти здесь: https://www.dropbox.com/s/vuf3jtrr2boq5eg/lad19-geo.json?dl=0
Кто-нибудь знает, что может быть причиной проблемы? Я предполагаю, что файлы .shp хороши, поскольку они отлично отображаются на mapshaper.org и QGis. Любая помощь будет принята с благодарностью.
Спасибо.