This repository explains how to make an animated map of Earth using open-source code and data from NASA, USGS, and Natural Earth. Software used includes Python 3.7.1
, Illustrator CC 2019
and Photoshop CC 2019
. If you have comments or suggestions for this tutorial, please let me know on my blog! You can also buy the finished map here if you like.
Python dependencies: matplotlib
numpy
cartopy
glob
pandas
jupyter
. Dependencies can be installed with pip install -r requirements.txt
.
Software Carpentry has great tutorials for installing Python (scroll down and follow the directions in the Bash Shell and Python sections), getting starting with Jupyter Notebooks, and beginner-friendly Python programming. After you've installed Python using these tutorials, you can use Git Desktop and the instructions in this tutorial to download the code and data in this tutorial.
You'll need software for editing raster and vector images (this article explains the difference). I use Adobe Photoshop and Illustrator, but you can also use the free open-source programs Gimp and Inkscape. There is no perfect software that fits everyone's needs, so you'll want to understand the pros and cons for the different raster and vector programs before choosing.
- Gathering and processing data
- Map design in Python
- Map design in Illustrator and Photoshop
- References
- License
NASA publishes many Earth datasets at monthly time scales, and this GIF uses one frame per month to show the fluctuating seasons. The animation focuses mainly on data about Arctic sea ice and vegetation, but it was hard to choose - NASA has many other beautiful seasonal datasets, like fire, temperature, or rainfall.
To show a few examples, the NASA Earth Observations website includes data on seasonal fire incidence (1), vegetation (2), solar insolation, or the amount of sunlight (3), cloud fraction (4), ice sheet coverage (5), and processed satellite images (6). My own map (7) combines the ice sheet data and the Blue Marble satellite images (6). The NEO database also has many more interesting datasets not shown here, like rainfall, chlorophyll concentration, or Carbon Monoxide.
The NASA Blue Marble: Next Generation image series is a digitally enhanced set of high-resolution Earth images available for every month in 2004. These satellite images have been edited by NASA to remove clouds and provide high spatial detail in many different types of surfaces (reflective glaciers, dark rainforests, and deep oceans). I downloaded each of these files as a JPEG
at the highest resolution (0.1 degrees).
In addition to the Blue Marble color images, NASA has many datasets available for download in CSV
format. These datasets are also available as images, but I decided to download the numerical data because some of the color schemes used by NASA didn't match my own map colors. By downloading the numerical data I could assign my own colormaps and fill in any small pieces of missing data.
To collect these datasets, go to the NASA Earth Observations website, select CSV
under the File Type
selector on the right hand menu, and then click on the desired file resolution (I used 0.1 degrees for these maps).
This project was one of my first maps in the series, so the code is a little less streamlined than my topographic maps or geology maps. For this animation I made each of the small inset corner maps separately from the large central map and combined the figures in Photoshop. However, it would have been much faster to use gridspec in matplotlib
to combine all five maps into the same image in Python. This file in the topographic map tutorial has a good example of this merging technique, if you're interested in replicating the five-panel map more efficiently.
For the labels on this map I used data from Natural Earth, a public domain mapping resource. Different types of map labels are stored in separate datasets, and for this map I downloaded the Natural Earth datasets for populated places, elevation points, glaciated areas, marine areas, and physical labels. I saved each of these as a separate PDF
file so I could change the style of each type of label separately in Illustrator.
To match the rest of the space map collection, I decided to emphasize the natural features of the Earth. So I didn’t include any country borders, country names, or other political information (though I did include large cities because I thought they counted as interesting physical features). Instead I tried to use labels that emphasized the capes, oceans, deserts and forests of the world.
At the time that I wrote this code, the cartopy
library had an issue that caused all text outside the boundaries of the map to be plotted in the very center. I tried several Python workarounds, but in the end it was fastest to zoom in to the center of each figure in Illustrator and manually remove all points plotted at the very center of the map. The issue may have been fixed in a subsequent cartopy
update, but if you're seeing something similar in your maps this might be the reason.
I used an Orthographic projection for this map to visualize what the Earth looks like from outer space. The NASA datasets are provided in Plate Carrée format, and cartopy
makes it easy to switch between commonly used projections like Plate Carrée and Orthographic. The same code in this repository can be used to create maps in any other supported projection by changing the axis projection variable plt.axes(projection=cartopy.crs.Orthographic())
.
Because this map is animated, the project involved a lot of Python output files. Some of the data stayed the same across all twelve months of the year (text labels, tectonic lines, coastlines, gridlines), but for other datasets I made a separate figure for each of the twelve frames (Blue Marble images, cloud cover, and solar insolation maps). To combine the separate images into one animated map, I first combined the static data together into one overlay layer. Next I pulled each of the twelve time-dependent figures into Photoshop and animated it using the Timeline
feature. I've previously written a detailed tutorial for animating in Photoshop, but you can also combine animation frames in many other programs (and even in Python itself).
I usually save figures as a PDF so I can edit the text and shapes in Illustrator. There are a couple standard commands I use to export Matplotlib figures so they're easy to edit:
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.backends.backend_pdf as pdf
# Export text as editable text instead of shapes:
matplotlib.rcParams['pdf.fonttype'] = 42
# Preserve the vertical order of embedded images:
matplotlib.rcParams['image.composite_image'] = False
# Remove borders and ticks from subplots:
ax.axis('off')
# Remove padding and margins from the figure and all its subplots
plt.margins(0,0)
plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
# Save the Matplotlib figure as a PDF file:
pp = pdf.PdfPages('./savename.pdf', keep_empty=False)
pp.savefig(fig)
pp.close()
# If I don't need to edit vector paths I save the file as a
# PNG so I can import it directly into Photoshop:
plt.savefig('./savename.png', format='png', dpi=600, pad_inches=0, transparent=True)
After saving the figure, the PDF
file needs to be edited so that each object can be manipulated individually. In Illustrator, select everything in the file and then go to Object
--> Clipping Mask
--> Release
. At this point you can also delete the background and axis border objects, if you included them in the output file.
I export Python figures to Illustrator and Photoshop because several great design features are impossible or very time-consuming in Matplotlib. I'm linking tutorials here for the features I use most often - font alternates and ligatures, custom brushes, layering effects, blur effects, gradients along a path, variable width paths, type on a path, and selecting objects by characteristic.
I've included a small section of the map in the figures
folder as the Photoshop file earth_sample.psd
. The file is small enough to upload online, but since it still has the original layers you should be able to use it as a reference for layering and color effects. I changed the colors of this map pretty significantly so that the dark labels would be legible across the globe.
I decided to annotate this map using text labels that followed the spherical contour lines of the planet. First I used Python to plot a series of latitude lines up and down the globe. I also made a Python output file that placed each text annotation next to a scatterpoint at the center of the feature. Finally I opened these files in Illustrator and manually combined each label with a nearby latitude line:
- Use the
Type on a Path
tool to copy and paste the text for each object onto an appropriate latitude vector. - Use
Character
->Set the baseline shift
to center the text vertically to the desired location.
To create a shadow effect around the text labels, first save the text as a transparent PNG
file and import it into Photoshop. Duplicate this annotation layer and go to Filter
--> Blur Gallery
--> Field Blur
. For shadow text I usually create two blur layers set to 20% opacity - one with a Blur
of 4px and the other 10px.
I wanted the maps in this series to look cohesive, so I made a palette of ~70 different colors and picked from these choices in every map. I also used the same two fonts (Redflowers and Moon) in all maps. You're welcome to use the color palette and font styling if you'd like.
To develop this set of colors, I started the project by designing 14 different color schemes. My initial idea was to have a unique color palette for every planet, but in the end I used the same collection of colors throughout all of the projects to make the maps look more cohesive.
Each color palette is shown in several different ways, because I wanted to design versatile color schemes that could work as discrete elements, or as pieces of a complex pattern, or as a gradient in topographic maps. I updated these three visualizations while designing to make sure each color scheme would work for each application.
For this project I wanted to combine large datasets with the hand-crafted design style of artists like William Morris or Alphonse Mucha. To organize my thoughts I collected a big folder of inspiration images from sources like the New York Public Library Digital Database:
When I started this project I initially wanted to design different border decorations for every topic. I sketched a collection of 18 different repeated patterns, each meant to go alongside a unique astronomy theme like planets, galaxies, space missions, or satellites.
But as the project continued I realized there was so much data that the detailed borders made the maps look too cluttered. In the end I removed all of the borders and designed just one scrollwork illustration to wrap around rounded map projections. In these round maps I thought the shift from detailed map to blank paper was a bit too abrupt, so this was a good compromise between data-heavy and illustrative design styles.
For this scrollwork design I started with a pencil sketch, and tried a couple different iterations of leafy scrolls before finally picking a less botanically inspired design. When I paint decorations like these in Photoshop, I begin each design as a solid white shape and then gradually break away pieces into detailed chunks. Next, I brush away pieces of each section with the brush eraser tool until the pieces look like a fully-shaded monochrome design. I wait to add color until the very last step, where I use many different colors and overlay layers for a richer effect.
I've included two different examples of these painted Photoshop illustrations in the figures
folder as scrollwork_sample.psd
and decorations_sample.psd
. These files still have the original layers, so you should be able to use it as a reference for layering, painting, and color effects.
- Astronomy. Andrew Fraknoi, David Morrison, Sidney C. Wolff et al. OpenStax 2016.
- Blue Marble: Next Generation Topography and Bathymetry. NASA Earth Observations 2004.
- Sea Ice Concentration and Snow Extent, Global (1 Day - SSM/I/DMSP). NASA Earth Observations 2017.
- Cloud Fraction (1 Month - AQUA/MODIS). NASA Earth Observations 2018.
- Solar Insolation (1 Month). NASA Earth Observations 2018.
- Earth True Color (1 Day - NPP/VIIRS). NASA Earth Observations 2019.
- Tectonic Plate Boundaries. USGS Spatial Services 2010.
- Natural Earth 1:10m Cultural Vectors Populated Places. Natural Earth v4.1.0
- Natural Earth 1:10m Physical Vectors River Centerlines. Natural Earth v4.1.0
- NASA Science Solar System Exploration. 2019.
- Earth's Atmospheric Layers. NASA 2013.
- Fonts: Moon by Jack Harvatt and RedFlower by Type & Studio.
- Advice: Thank you to Chloe Pursey and Leah Willey for their helpful advice in making this map.
Code: All of the code in this repository is shared under the GPL-3.0 license.
Data: The data in this repository belongs to the original authors of the data. Please use the references section to look up the original version. In cases where I edited or revised the data, I impose no additional restrictions to the original license. Any data files I created myself are shared under the ODC Open Database License.
Artwork: The artwork included in this repository are shared under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.