Plotting to Maps in Python

August Radjoe
3 min readApr 2, 2020

--

You won’t believe how simple this shit is.

Deck.gl is my favourite visualisation tool for realtime data: Easy to deply, can fit in well with other frameworks, super simple for real-time data.

But at some point, I wanted to get back into Python data visualisation, so here we are. The code is here. I am using APIs and SHX files, you can use CSVs.

First, import the modules (After you install them, of course):

import requestsimport geopandas as gpdimport pandas as pdimport matplotlib.pyplot as plt

Now, if you’re on Windows, installing Geopandas is a pain in the ass. Check this out though, it solved everything for me.

Once we are done, let’s get that data. I am using an API to fetch India’s statewise data for Coronavirus.

url = "https://covid19-india-adhikansh.herokuapp.com/states"response = requests.get(url)response = response.json()response = dict(response)response = response["state"]confirmed = []for i in range(len(response)):   del response[i]['_id']   del response[i]['total']   confirmed.append(response[i]['confirmed'])df = pd.DataFrame.from_dict(response)print(df)

You should get this output. It is a dataframe of all the states and their cases. We first fetched the API (https://covid19-india-adhikansh.herokuapp.com/states) using the request library, saved it in a variable and turned it into a dictionary. A little looping and we got rid of ID and total (I had a feeling total was not calculated to give result meaningful to our scope). We turn the dictionary to dataframe and WOOHOO we get that breaaaaad.

Next up, loading the map of India. Go to Diva-GIS (https://www.diva-gis.org/gdata) and download the ZIP file of your country. Then go ahead and extract the ZIP, you will see a few types of files. Now I am using SHX or SHP, you can use the other files. In essence, they are just files that contain geometrical measurements for forming a polygon.

fp = "IND_adm1.shx"map_df = gpd.read_file(fp)map_df.plot()print(map_df)

Running the code above should fetch you your map. I am also printing the map’s values, and since I am loading via Geopandas, I am essential loading it as a dataframe.

Let’s go ahead and merge the map’s dataframe and the dataframe of the data.

merged = map_df.join(df)merged = merged.dropna()merged = merged[['name', 'geometry', 'death', 'cured', 'confirmed']]print(merged)

We also dropped off the NaN values. You should get something like the code below.

Let’s map this shit.

Set the variable that you need to map this on.

variable = 'confirmed'

Find the maximum and the minimum values that we have to map in.

vmin = 0vmax = max(confirmed)

Now let’s go ahead and declare fig and ax variables as subplot instances. Turn off the axis and set the properties of the map. ‘OrRd_r’ is a Red gradient for the map.

fig, ax = plt.subplots(1, figsize=(30, 10))
ax.axis('off')
ax.set_title('Confirmed Cases by State in India', fontdict={'fontsize': '25', 'fontweight' : '3'})sm = plt.cm.ScalarMappable(cmap='OrRd_r',norm=plt.Normalize(vmin=vmin, vmax=vmax))

Now set an empty array to the ‘sm’. Add the colorbar and finally: Create the Map.

sm.set_array([]) # or alternatively sm._A = []. Not sure why this step is necessary, but many recommends itfig.colorbar(sm)merged.plot(column=variable, cmap='OrRd_r', linewidth=0.8, ax=ax, edgecolor='0.8')

And there ya go lads, we have the final map!

Send me money now.

Mir.

--

--

August Radjoe

Now: MS CS @ Boston U / Prev: Ignite Tournaments, DeFi Alliance, Persistence, Eth India Co