Reputation: 11
I have a list of city names all within a country, and I want to use plotly to build a bubble map of the listed cities, where the size of each bubble is relative to how many times a given city is listed.
So far I am able to generate the empty map with plotly express, But in terms of displaying the actual data I am unsure how to proceed.
I understand that a lot of the examples on the plotly website use dataframes, which makes me think that I will need to generate one from this list. In particular, the third example on the linked page above uses lat/longitude to locate the bubbles. Is there a way to graph the bubbles from the city names directly? Otherwise, how can I approach this?
Thanks for any help, as I am not terribly familiar with plotly.
Upvotes: 1
Views: 2064
Reputation: 31166
delist
dflist.groupby("city", as_index=False).size()
merge(dfuk, on="city")
import sys, requests, urllib
import pandas as pd
from pathlib import Path
from zipfile import ZipFile
import plotly.express as px
# fmt: off
# download data set, world cities including GPS co-ordinates
url = "https://simplemaps.com/static/data/world-cities/basic/simplemaps_worldcities_basicv1.74.zip"
f = Path.cwd().joinpath(f'{urllib.parse.urlparse(url).path.split("/")[-1]}.zip')
if not f.exists():
r = requests.get(url, stream=True, headers={"User-Agent": "XY"})
with open(f, "wb") as fd:
for chunk in r.iter_content(chunk_size=128):
fd.write(chunk)
zfile = ZipFile(f)
dfs = {f.filename: pd.read_csv(zfile.open(f)) for f in zfile.infolist() if f.filename.split(".")[1]=="csv"}
# fmt: on
# just UK cities.. with GPS
dfuk = dfs["worldcities.csv"].loc[lambda d: d["iso3"].eq("GBR")]
# dataframe referred to in question, cities listed multiple times
n_cities = 20
p = np.geomspace(0.01, 1, n_cities)
p = p / p.sum()
dflist = pd.DataFrame({"city": np.random.choice(dfuk.sample(n_cities)["city"], 500, p=p)})
px.scatter_mapbox(
dflist.groupby("city", as_index=False).size().merge(dfuk, on="city"),
lat="lat",
lon="lng",
hover_name="city",
size="size",
).update_layout(mapbox={"style": "carto-positron", "zoom": 4}, margin={"t":0,"b":0,"l":0,"r":0})
Upvotes: 1