I’ve been trying to figure out how to plot shapefiles using plotly. I think I’ve figured out how to polygon and point shapefiles. But I’m still stuck on polylines.
The following code seems to plot polylines properly:
# Imports
import pandas as pd
import geopandas as gpd
import plotly.express as px
# Read data
sp_roads = gpd.read_file('/vsicurl/https://github.com/Alwayz247/spdata/raw/main/Roads.shp')
sp_roads_projected = sp_roads.to_crs(4326)
# Get coordinates
df_roads = sp_roads_projected.get_coordinates().reset_index()\
.merge(sp_roads_projected[['FULLNAME']].reset_index(), on='index')
# Plot
fig = px.line_mapbox(df_roads,
lon=df_roads['x'],
lat=df_roads['y'],
line_group=df_roads['index'],
hover_name=df_roads['FULLNAME'],
mapbox_style="open-street-map",
center={"lat": 37.0902, "lon": -95.7129},
zoom=2)
fig.update_layout(margin=dict(l=0, r=0, t=0, b=0))
fig.show()
But if I want to add a legend called “Roads” so that I can turn this layer on or off, I get a separate entry in the legends for each line group.
fig = px.line_mapbox(df_roads,
lon=df_roads['x'],
lat=df_roads['y'],
line_group=df_roads['index'],
hover_name=df_roads['FULLNAME'],
mapbox_style="open-street-map",
center={"lat": 37.0902, "lon": -95.7129},
zoom=2)\
.update_traces(visible=True,
name='Roads',
showlegend=True)
fig.update_layout(margin=dict(l=0, r=0, t=0, b=0))
fig.show()
It’s easy to plot polylines using cloropleth_mapbox() without the need to extract the coordinates, since I can just use the geojson argument. That does not seem possible with line_mapbox. What is the best way to plot polylines using plotly?
Ultimately, I want a plot with multiple spatial features and legends which I can use to turn each layer on or off. Something like the following. In this case, plotly only plots the first polyline feature for some reason.
# Imports
import pandas as pd
import geopandas as gpd
import plotly.express as px
# Read data
sp_capitals = gpd.read_file('/vsicurl/https://github.com/Alwayz247/spdata/raw/main/Capitals.shp')
sp_roads = gpd.read_file('/vsicurl/https://github.com/Alwayz247/spdata/raw/main/Roads.shp')
sp_states = gpd.read_file('/vsicurl/https://github.com/Alwayz247/spdata/raw/main/States.shp')
sp_capitals _projected = sp_capitals.to_crs(4326)
sp_roads_projected = sp_roads.to_crs(4326)
sp_states _projected = sp_states.to_crs(4326)
# Get coordinates
df_roads = sp_roads_projected.get_coordinates().reset_index()\
.merge(sp_roads_projected[['FULLNAME']].reset_index(), on='index')
# Plot
fig = px.choropleth_mapbox(mapbox_style="open-street-map",
center={"lat": 37.0902, "lon": -95.7129},
zoom=2)
fig1 = px.choropleth_mapbox(sp_states_projected.eval('prop_water=AWATER/ALAND'),
locations=sp_states_projected.index,
geojson=sp_states_projected.geometry,
color='prop_water',
hover_name=sp_states_projected['NAME'])\
.update_traces(visible=True,
name='States',
showlegend=True)
fig2 = px.line_mapbox(df_roads,
lon=df_roads['x'],
lat=df_roads['y'],
line_group=df_roads['index'],
hover_name=df_roads['FULLNAME'])\
.update_traces(visible=True,
name='Roads',
showlegend=True)
fig3 = px.scatter_mapbox(sp_capitals_projected,
lon=sp_capitals_projected.geometry.x,
lat=sp_capitals_projected.geometry.y,
hover_name=sp_capitals_projected['name'])\
.update_traces(visible=True,
name='State Capitals',
showlegend=True)
fig.add_trace(fig1.data[0])
fig.add_trace(fig2.data[0])
fig.add_trace(fig3.data[0])
fig.update_layout(legend=dict(xanchor='right',
yanchor='bottom',
x=1,
y=0.1),
coloraxis_colorbar=dict(title='Water%',
orientation='h',
xanchor='left',
yanchor='bottom',
x=0,
y=0,
thickness=10,
len=0.5))
fig.update_layout(margin=dict(l=0, r=0, t=0, b=0))
fig.show()