The easiest way to plot data from Pandas on a world map
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()
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")
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()
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")
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")
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()
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
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 :)