can someone tell me how to draw a world map and indicate 10-15 countries on it using matplotlib/folium ? I downloaded 'world-countries.json', so got world map (in Jupyter notebooks):
import folium
import json
import pandas as pd
import pathlib
world_path = pathlib.Path('world-countries.json')
with open(world_path) as f:
world = json.load(f)
from folium import GeoJson
m = folium.Map(tiles=None)
GeoJson(world).add_to(m)
data = pd.read_csv('15_countires.csv')
data.shape
map.choropleth(geo_data=world_path, data=data,
columns=['CountryCode'],
key_on='feature.id',
fill_color='YlGnBu', fill_opacity=0.7, line_opacity=0.2)
But how to indicate countries on it and color them ? Or, maybe, I can do it without geojson, only using folium ?
Took this a bit further than the question. It is very simple to do
pandas
mostly because I'm familiar with it for preparing and then using the data.import requests, json, re, folium
from bs4 import BeautifulSoup
import pandas as pd
# dynamically get the world-country boundaries
res = requests.get("https://raw.githubusercontent.com/python-visualization/folium/master/examples/data/world-countries.json")
df = pd.DataFrame(json.loads(res.content.decode()))
df = df.assign(id=df["features"].apply(pd.Series)["id"],
name=df["features"].apply(pd.Series)["properties"].apply(pd.Series)["name"])
# build a dataframe of country colours scraped from wikipedia
resp = requests.get("https://en.wikipedia.org/wiki/National_colours",)
soup = BeautifulSoup(resp.content.decode(), "html.parser")
colours = []
for t in soup.find_all("table", class_="wikitable"):
cols = t.find_all("th")
ok = (len(cols)>5 and cols[0].string.strip()=="Country" and cols[4].string.strip()=="Primary")
if ok:
for tr in t.find_all("tr"):
td = tr.find_all("td")
if len(td)>5:
sp = td[4].find_all("span")
c1 = re.sub("background-color:([\w,#,0-9]*).*", r"\1", sp[0]["style"])
c2 = c1 if len(sp)==1 else re.sub("background-color:([\w,#,0-9]*).*", r"\1", sp[1]["style"])
colours.append({"country":td[0].find("a").string,
"colour1":c1,
"colour2":c2,
})
dfc = pd.DataFrame(colours).set_index("country")
# a list of interesting countries - Singapore is missing!
countries = ["Singapore","Malaysia","Indonesia","Vietnam","Philippines"]
# style the overlays with the countries own colors...
def style_fn(feature):
cc = dfc.loc[feature["properties"]["name"]]
ss= {'fillColor':f'{cc[0]}', 'color':f'{cc[1]}'}
return ss
# create the base map
m = folium.Map(location = [1.34, 103.82],
zoom_start=6,
control_scale=True)
# overlay desired countries over folium map
for r in df.loc[df["name"].isin(countries)].to_dict(orient="records"):
folium.GeoJson(r["features"], name=r["name"], tooltip=r["name"], style_function=style_fn).add_to(m)
m