Reputation: 40
I am plotting a map using plotly express and geojson file.I want to show static values on the individual district. Currently those values are visible on hover, but I want the values to be seen all the time even without hovering on it.
This is my code:
import json
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.io as pio
x = json.load(open("./odisha_disticts.geojson","r"))
user_data = []
for i in range(len(x['features'])):
d = x['features'][i]['properties']
d['Females'] = np.random.randint(0,100,1)[0]
user_data.append(d)
df = pd.DataFrame(user_data)
df.head()
ID_2 NAME_2 Females
0 16084 Angul 19
1 16085 Baleshwar 45
2 16086 Baragarh 52
3 16087 Bhadrak 81
4 16088 Bolangir 49
fig = px.choropleth(
df,
locations="ID_2",
featureidkey="properties.ID_2",
geojson=x,
color="Females"
)
fig.update_geos(fitbounds="locations", visible=False)
px.scatter_geo(
df,
geojson=x,
featureidkey="properties.NAME_2",
locations="District",
text = df["District"]
)
fig.show()
The link to required files is HERE
Upvotes: 0
Views: 782
Reputation: 35205
To annotate on a map, use a graph_object
to go.Choroplethmapbox
with go.Scattermapbox
with textmode. As a preparation before creating the graph, we need the latitude and longitude for the annotation, so we use geopandas to read the geojson file and find the center of geometry. A warning is displayed at this point because the loaded geometry uses an inappropriate geodetic system to calculate the center. If you have a latitude and longitude you wish to use for your annotations use it. There are two caveats in creating the map: first, you will need the free Mapbox API token. Get it here. second, in go.Scattemapbox(), the mode is text + marker, but if you use text only, an error will occur. The reason is unknown.
import geopandas as gpd
import pandas as pd
import plotly.graph_objects as go
# read your data
data = pd.read_csv('./data.csv', index_col=0)
# read geojson
x = json.load(open("./odisha_disticts.geojson","r"))
gdf = gpd.read_file('./odisha_disticts.geojson')
gdf['centroid'] = gdf['geometry'].centroid
gdf['lon'] = gdf['centroid'].map(lambda p:p.x)
gdf['lat'] = gdf['centroid'].map(lambda p:p.y)
gdf.head()
ID_2 NAME_2 geometry centroid lon lat
0 16084 Angul POLYGON ((85.38891 21.17916, 85.31440 21.15510... POINT (84.90419 20.98316) 84.904186 20.983160
1 16085 Baleshwar POLYGON ((87.43902 21.76406, 87.47124 21.70760... POINT (86.90547 21.48738) 86.905470 21.487376
2 16086 Baragarh POLYGON ((83.79293 21.56323, 83.84026 21.52344... POINT (83.34884 21.22068) 83.348838 21.220683
3 16087 Bhadrak POLYGON ((86.82882 21.20137, 86.82379 21.13752... POINT (86.61598 20.97818) 86.615981 20.978183
4 16088 Bolangir POLYGON ((83.45259 21.05145, 83.44352 21.01535... POINT (83.16839 20.58812) 83.168393 20.588121
import plotly.express as px
import plotly.graph_objects as go
mapbox_token = open("mapbox_api_key.txt").read()
fig = go.Figure()
fig.add_trace(go.Scattermapbox(lat=gdf['lat'],
lon=gdf['lon'],
mode='text+markers',
textposition='top center',
text = [str(x) for x in data["District"]],
textfont=dict(color='blue')
))
fig.add_trace(go.Choroplethmapbox(geojson=x,
locations=data['id'],
z=data['Females'],
featureidkey="properties.ID_2",
colorscale='Reds',
zmin=0,
zmax=data['Females'].max(),
marker_opacity=0.8,
marker_line_width=0
)
)
fig.update_layout(height=600,
mapbox=dict(
center={"lat": gdf['lat'].mean(), "lon": gdf['lon'].mean()},
accesstoken=mapbox_token,
zoom=5.5,
style="light"
))
fig.show()
Upvotes: 1