I like to keep track of my life; collecting data about random things–one of them happens to be my travel patterns. While visualizing my own travels I started to wonder what the global airport network might look like. I remember reading about the structure of the airport network in the architecture of complex weighted networks by A. Barrat et al. but the paper never visualized the network. To figure it out, I first needed some data, luckily OpenFlights.org has a database of routes as well as airports, which allows us to create some pretty nice looking visualizations (see above figure).
First lets import some packages, there are tons of good plotting libraries, I personally love matplotlib because it allows you to customize everything.
import matplotlib.pyplot as plt from mpl_toolkits.basemap import Basemap import pandas as pd import numpy as np from collections import Counter import random
Next let’s load the data. As multiple airline companies can fly the same route I have chosen to count the number of flights between airports and weight links between cities accordingly.
# load airport data data = pd.read_csv('airports.csv') # load route data edges = Counter() with open('routes.csv') as f: next(f) for line in f: airline,airline_id,source,source_id,destination,destination_id,codeshare,stops,equipment = line.split(',') edges[min(source_id,destination_id),max(source_id,destination_id)] += 1 pos = dict(map(lambda x: (str(x),(x,x)), data[['airport_id','longitude','latitude']].values))
Finally we define a plotter function, here I use basemaps to draw the globe (using an orthographic projection) and to plot routes (using great circles). Unfortunately we need to use a hack as the function drawgreatcircle will give wrong results if the end points of the great circle are not located in the same field of view.
def world(lat0,lon0,color): # construct map projection m = Basemap(projection='ortho',lat_0=lat0,lon_0=lon0,resolution='c') # draw coastlines, country boundaries, fill continents. #m.drawcoastlines(linewidth=0.1,color='white') m.fillcontinents(color='#515151',lake_color='#282828') # draw the edge of the map projection region (the projection limb) m.drawmapboundary(fill_color='#282828') # transform points count = 0 for (ei,ej),w in edges.items(): if ei in pos and ej in pos: # draw routes # get coordinates for great circle x, y = map(np.array,m.gcpoints(pos[ei],pos[ei],pos[ej],pos[ej], 150)) m.plot([x[j] for j in range(len(x)) if x[j] < 10e20 and y[j] <= 10e20], # small hack [y[j] for j in range(len(y)) if x[j] < 10e20 and y[j] <= 10e20],color=color,lw=w*0.1,alpha=0.1)
To create the above figure we use:
# draw points on globe plt.figure(figsize=(12,3)) plt.subplot(1,4,1) world(0,-90,'#00AEEF') plt.subplot(1,4,2) world(0,0,'#00AEEF') plt.subplot(1,4,3) world(0,90,'#00AEEF') plt.subplot(1,4,4) world(0,180,'#00AEEF') plt.tight_layout() plt.savefig('airports.png',transparent=True,dpi=300) plt.close()
Varying the lat0 and long0 parameters allows us to rotate the globe. Combining this with imagemagick and choosing a bit more gloomy color scheme we can create the below gif.