Felt a little left out, so I decided to make a port in Python. You can follow along below or if you prefer this as an Jupyter Notebook that you can download and run on our local machine.
To start with you need the packages
matplotlib basemap. The latter should only be installed through Anaconda which is your, from here on, favorite Python package installer. So let’s load them up.
import numpy as np import matplotlib.pyplot as plt %matplotlib inline from mpl_toolkits.basemap import Basemap
Kristoffer favored the Winkel tripel projection since it’s adapted by the National Geographic Society. But since it’s unfortunaly not avalible in Basemap, we use Kavrayskiy 7 (
kav7), which is very very close. And by the way, Basemap supports 34 different projections so you will probably be able to find something that suits you.
m = Basemap(resolution='c', projection='kav7', lat_0=0., # Center around lon_0=0.) # lat 0, lon 0
Kristoffer used graticlues (the grid) from a shapefile,
Basemap handles this for us so let’s prepare what it need.
n_graticules = 18 parallels = np.arange(-80., 90, n_graticules) meridians = np.arange(0., 360., n_graticules) lw = 1 dashes = [5,7] # 5 dots, 7 spaces... repeat graticules_color = 'grey'
The rest should be quite self explainatory.
fig1 = plt.figure(figsize=(16,20)) fig1.patch.set_facecolor('#e6e8ec') ax = fig1.add_axes([0.1,0.1,0.8,0.8]) m.drawmapboundary(color='white', linewidth=0.0, fill_color='white') m.drawparallels(parallels, linewidth=lw, dashes=dashes, color=graticules_color) m.drawmeridians(meridians, linewidth=lw, dashes=dashes, color=graticules_color) m.drawcoastlines(linewidth=0) m.fillcontinents('black', lake_color='white') m.drawcountries(linewidth=1, linestyle='solid', color='white', zorder=30) title = plt.title('World map (Kavrayskiy 7)', fontsize=20) title.set_y(1.03) # Move the title a bit for niceness
Let’s add some shapefiles. Basemap does this nicely for us with
readshapefile and we use the same as Kristoffer found here. Since we named it
m.populated_places_info will hold all data. For some shapefiles this means statistics and all sorts of nice things so be sure to check
m.scatter to make the bubble plot.
m.readshapefile('shapefiles/ne_110m_populated_places/ne_110m_populated_places', name='populated_places', drawbounds=False, color='none') populations = [r['POP2000'] for r in m.populated_places_info] lats = [r['LATITUDE'] for r in m.populated_places_info] lons = [r['LONGITUDE'] for r in m.populated_places_info] x1, y1 = m(lons, lats) # Convert coords to projected place in figure m.scatter(x1, y1, s=np.array(populations)*0.05, marker="o", color='#32caf6', zorder=10, alpha=0.8)
But most likely a shapefile will contain a shape that you want to put on your map. Let’s put out the borders of the tectonic plates on our map. The tectonic plate shapefile can be found here.
m.readshapefile('shapefiles/tectonicplates-master/PB2002_plates', name='tectonic_plates', drawbounds=True, color='red')
But you’ll probably also want to have control over the settings of the shapes e.g. color the Australia plate in a different way
for info, shape in zip(m.tectonic_plates_info, m.tectonic_plates): if info['PlateName'] == "Australia": x, y = zip(*shape) m.plot(x, y, marker=None, color='b')
And perhaps you also want to fill the patch.
from matplotlib.patches import Polygon from matplotlib.collections import PatchCollection from matplotlib.patches import PathPatch patches =  for info, shape in zip(m.tectonic_plates_info, m.tectonic_plates): if info['PlateName'] == "Australia": patches.append(Polygon(np.array(shape), True)) ax.add_collection(PatchCollection(patches, facecolor='#32caf6', edgecolor='none', linewidths=1., alpha=0.5, zorder=1))