The easiest way to plot data from Pandas on a world map

Udi Yosovzon
Towards Data Science
4 min readFeb 13, 2021

--

This guide is intended to be quick and easy, with the least amount of words and least amount of code, to show you how to plot data from a Pandas object on a world map using Matplotlib and Geopandas libraries.

The python libraries you need to install are pandas, geopandas and matplotlib. You can find the code for this tutorial on github: https://github.com/udiy/blogposts/tree/main/Easy%20map

The data in the Pandas object needs to have location coordinates, which means latitude and longitude. For this article, I am using data about fires in Australia, which can be found here: https://www.kaggle.com/carlosparadis/fires-from-space-australia-and-new-zeland.

The data comes from NASA satellites MODIS instrument, they monitor the fires from space, find acknowledgments at the end of this article. In the data, there’s a column called brightness, which is a measure of the temperature (in Kelvin) of the fire.

Explore data

Let’s see some code now. First, we’ll have a quick look at loading and peeking at the data:

df = pd.read_csv("fire_archive_M6_96619.csv", 
usecols=["latitude", "longitude", "brightness",
"acq_date"], parse_dates=["acq_date"])
df.head()
Output of the above code cell

Now let’s plot the data on a scatter plot, latitude on the y-axis, longitude on the x-axis:

df.plot(x="longitude", y="latitude", kind="scatter", c="brightness",
colormap="YlOrRd")
Output of the above cell

Nice. Even without the use of a map, we can see the contours of Australia. Let’s add a map.

Geopandas

Geopandas lets you load the geometry for countries worldwide into an object called GeoDataFrame, which is very similar to pandas DataFrame object. It looks like this:

countries = gpd.read_file(
gpd.datasets.get_path("naturalearth_lowres"))
countries.head()
Output of the above cell

Once you have this object you can easily plot a world map, in the same way you would use the plot function in pandas:

countries.plot(color="lightgrey")
Output of the above cell

Since our focus is on Australia, we can slice the “countries” object so it shows us Australia only:

countries[countries["name"] == "Australia"].plot(color="lightgrey")
Output of the above cell

Putting it all together

We’ll now use matplotlib to create a figure, and plot the map and the data together at the same time:

# initialize an axis
fig, ax = plt.subplots(figsize=(8,6))
# plot map on axis
countries = gpd.read_file(
gpd.datasets.get_path("naturalearth_lowres"))
countries[countries["name"] == "Australia"].plot(color="lightgrey",
ax=ax)
# parse dates for plot's title
first_month = df["acq_date"].min().strftime("%b %Y")
last_month = df["acq_date"].max().strftime("%b %Y")
# plot points
df.plot(x="longitude", y="latitude", kind="scatter",
c="brightness", colormap="YlOrRd",
title=f"Fires in Australia {first_month} to {last_month}",
ax=ax)
# add grid
ax.grid(b=True, alpha=0.5)
plt.show()
Output of the above cell

Bonus — Extra Styling

Minor grid

The grid lines correspond to the ticks on both axes. Depending on the zoom level and our target on the map, we might want to add grid lines with smaller spacing, to do that we need to add extra ticks. For styling purposes, I prefer to add minor ticks, this way you can plot the minor grid in a different color, or transparency level. In the example below there is a minor grid with a spacing of 1 degree:

# get axes limits
x_lo, x_up = ax.get_xlim()
y_lo, y_up = ax.get_ylim()
# add minor ticks with a specified sapcing (deg)
deg = 1
ax.set_xticks(np.arange(np.ceil(x_lo), np.ceil(x_up), deg), minor=True)
ax.set_yticks(np.arange(np.ceil(y_lo), np.ceil(y_up), deg), minor=True)
ax.grid(b=True, which="minor", alpha=0.25)
fig
Output of the above cell

Acknowledgments

We acknowledge the use of data and/or imagery from NASA’s Fire Information for Resource Management System (FIRMS) (https://earthdata.nasa.gov/firms), part of the NASA Earth Observing System Data and Information System (EOSDIS).

MODIS Collection 6 NRT Hotspot / Active Fire Detections MCD14ML distributed from NASA FIRMS. Available on-line [https://earthdata.nasa.gov/firms]. doi: 10.5067/FIRMS/MODIS/MCD14ML

Disclaimer by NASA: https://earthdata.nasa.gov/earth-observation-data/near-real-time/citation#ed-lance-disclaimer

That’s it, I hope you found this tutorial helpful and enjoyable :)

--

--