I want to create an interactive map with two variables, Number of Farms and Number of Cattle Heads. I already have code where I can visualize the quantity of farms on a choropleth map, but I want to display bubbles of varying sizes on top of the choropleth map to visualize the data for the number of cattle heads.
I already have existing code, can you help me add the second variable?
Code:
import pandas as pd
import numpy as np
import plotly.graph_objs as go
import plotly.offline as pyo
df = pd.read_excel(‘Finca.xlsx’)
df
#I understand that to add the points or bubbles, I need specific latitude and longitude coordinates. I will be filling in the Excel file with the missing latitude and longitude data.
import json
from urllib.request import urlopen
with urlopen(‘https://gist.githubusercontent.com/aVolpe/0e1b1e6e25efafa8185d/raw/aa3d93f52e95a82733f8a29aa7044ec42cb74a03/paraguay.json’) as response:
counties = json.load(response)
locs = df[‘Departamento’]
for loc in counties[‘features’]:
loc[‘id’] = loc[‘properties’][‘dpto_desc’]
fig = go.Figure(go.Choroplethmapbox(
geojson=counties,
locations=locs,
z=df[‘Nro Fincas’],
colorscale=‘Viridis’,
colorbar_title=“Numero de Fincas”))
fig.update_layout(mapbox_style=“carto-positron”,
mapbox_zoom=5,
mapbox_center = {“lat”: -25.3006600, “lon”: -57.6359100})
fig.show()
Hi @Gillopy, welcome to the forum.
I think you can solve your problem by reading this thread: Annotations on plotly Choropleth + choropleth_mapbox + Scattermapbox - #5 by hoatran
We don’t have your data so you can refer below code:
import plotly.express as px
import geopandas as gpd
import plotly.graph_objects as go
import pandas as pd
from urllib.request import urlopen
import json
europe = pd.read_csv('https://raw.githubusercontent.com/softhints/Pandas-Exercises-Projects/main/data/europe_pop.csv')
lats = europe['lat']
lons = europe['lon']
text= (europe['pop_est']/1000000).round(decimals=0).astype(str)
with urlopen('https://raw.githubusercontent.com/leakyMirror/map-of-europe/master/GeoJSON/europe.geojson') as response:
counties = json.load(response)
fig = go.Figure()
fig.add_trace(go.Scattermapbox(lat=lats,
lon=lons,
mode='text+markers',
text=text,
textfont=dict(
family="san serif",
size=15),
textposition='top center',
marker_size=europe['pop_est']/1000000))
fig.add_trace(go.Choroplethmapbox(geojson=counties,
locations=europe['name'],
z=europe['pop_est'],
colorscale="Reds",
featureidkey="properties.NAME",
marker_opacity=0.8,
marker_line_width=0))
fig.update_layout(title_text ='Europe',
title_x =0.5,
width=1200,
height=1200,
mapbox = dict(center= dict(lat=52.370216, lon=4.895168),
accesstoken= "your_token",
zoom=3,
style="light"
)
)
fig.show()
*Note: You have to add your map_box token in accesstoken
2 Likes
Hello, thank you for the welcome.
I see that the code you provided is exactly what I was looking for, but it’s too complicated for me as I’m new to this.
When you mention providing my token access, which API are you referring to? I’m not registered on any website that offers map access. How could I solve this?
I had to do some statistics in the Excel file to convert the livestock count into relative percentage values so that they correspond to the sizes in the chart.
Excel File
import pandas as pd
import numpy as np
import plotly.graph_objs as go
import plotly.offline as pyo
df = pd.read_excel('Finca.xlsx')
df
import json
from urllib.request import urlopen
with urlopen('https://gist.githubusercontent.com/aVolpe/0e1b1e6e25efafa8185d/raw/aa3d93f52e95a82733f8a29aa7044ec42cb74a03/paraguay.json') as response:
counties = json.load(response)
lats = df['Latitud']
lons = df['Longitud']
locs = df['Departamento']
bubble_sizes = df['ganadox2'] # Specify the sizes for the bubbles
for loc in counties['features']:
loc['id'] = loc['properties']['dpto_desc']
fig = go.Figure(go.Choroplethmapbox(
geojson=counties,
locations=locs,
z=df['Nro Fincas'],
colorscale='Viridis',
colorbar_title="Numero de Fincas"))
fig.add_trace(go.Scattermapbox(
lat=lats, # Replace with your actual latitude data
lon=lons, # Replace with your actual longitude data
mode='markers',
marker=dict(
size=bubble_sizes, # Replace with your actual bubble size data column
color='red', # You can set the color as desired
opacity=0.8,
),
text=df['Departamento'], # Replace with labels or tooltips for the bubble
))
fig.update_layout(mapbox_style="carto-positron",
mapbox_zoom=5,
mapbox_center = {"lat": -25.3006600, "lon": -57.6359100})
fig.show()
I have added a few lines to the code and achieved a result like this.
Could you modify my code so that the labels can be displayed more elegantly? I would also like to add legends of different sizes to visualize the bubbles; the idea would be to see them on the right side alongside the other legend.
Something like this.
If the processing of go.Scattertermapbox is changed to a loop process for each row of the data frame, a legend with a different marker size is created for each row. However, no grouping of marker sizes is performed.
3 Likes
To make that I think you will need do something as below:
- Make a new columns in your dataframe that define size of bubble.
showlegend
must set as True and you will need to arrange legend position.
- Legend setting should add
itemsizing = 'trace'
.
Below is my sample code:
import pandas as pd
import numpy as np
import plotly.graph_objs as go
import plotly.offline as pyo
df = pd.read_excel('Finca.xlsx')
df = df.sort_values(['size'], ascending=[True])
df['size'] = df['size'].astype(str)
import json
from urllib.request import urlopen
with urlopen('https://gist.githubusercontent.com/aVolpe/0e1b1e6e25efafa8185d/raw/aa3d93f52e95a82733f8a29aa7044ec42cb74a03/paraguay.json') as response:
counties = json.load(response)
lats = df['Latitud']
lons = df['Longitud']
locs = df['Departamento']
bubble_sizes = df['ganadox2'] # Specify the sizes for the bubbles
for loc in counties['features']:
loc['id'] = loc['properties']['dpto_desc']
fig = go.Figure(go.Choroplethmapbox(
geojson=counties,
locations=locs,
z=df['Nro Fincas'],
colorscale='Viridis',
colorbar_title="Numero de Fincas"))
for s in df['size'].unique():
df2 = df[df['size'] == s]
fig.add_trace(go.Scattermapbox(
lat=df2['Latitud'], # Replace with your actual latitude data
lon=df2['Longitud'], # Replace with your actual longitude data
mode='markers', name = s,
marker=dict(
size=df2['ganadox2'], # Replace with your actual bubble size data column
color='red', # You can set the color as desired
opacity=0.8,
),
text=df['Departamento'], # Replace with labels or tooltips for the bubble
))
fig.update_layout(mapbox_style="carto-positron",
mapbox_zoom=5, showlegend = True, legend=dict(itemsizing = 'trace',
yanchor='top',
y=0.6,
xanchor='right',
x=1.3),
mapbox_center = {"lat": -25.3006600, "lon": -57.6359100})
fig.show()
Hope this help.
1 Like
I understand, I will try to research the manual more to be able to apply that. Thanks!
It was what I was looking for, thank you!