A flight map to call my own
/I enjoy both looking at and making maps, and given my penchant for travel it seems only natural to make travel maps. Previous mapping projects have involved the locations at which I have taken photos and travel expenses at various European locations. At some point, I decided that it would be cool to visualise the flights I have taken during my lifetime, and so here we are.
The planning
There are no shortage of flight maps around, for example both of these are lovely. I was after something a little more presonalised, which meant getting my hands dirty. The first question was that of language, which for me is a choice between Python and Mathematica. I have increasingly been using Python, to the point that it is almost all I use currently; however I still prefer the graphics generated from Mathematica. As the point of this exercise is generate a graphic, I decided to use Mathematica.
The data
Unfortunately, I have no nifty way of collecting my own travel data. There is no database I can scrape, so I had to compile my own list. This did not take that long, but was slightly tedious. I made a spreadsheet with four columns: origin, destination, year and outgoing. These should be self explanatory, except for outgoing which I decided to put in as a Boolean for whether I was leaving or returning. Thus far, I have used neither year nor outgoing, but perhaps they’ll be useful in the future. In terms of origin and destination, I used the International Air Travel Associated (IATA) three-letter airport codes to streamline the data processing. Although Mathematica’s AirportData function can in principle handle cities as inputs, I found that to be unreliable. On the other hand, I experienced no issues using the IATA codes, which quite frankly surprised me, especially for Aeródromo Guardiamarina Zañartu (WPU) in Chile.
The code
Much of the heavy lifting was executed by the in-built function AirportData, providing coordinates for the airports. From these, it is easy to construct a list of flights to plot using a combination of GeoGraphics and GeoPath. Obviously, there is a bit of styling to be done, for which much of my inspiration came from this map. In addition to a world flight map, I saw fit to make maps of both Australia and Europe, given I have called both of these places home, and this is borne out in the maps.
The source code can be found at the bottom of the page.
The result
I think the outcome is neat. Most obviously, you can see that I have lived in both Melbourne and Paris; my time around Frankfurt is less clear. It is apparent that I have primarily flown with middle-eastern airlines, but also that I have visited/transited through Singapore many times. In Australia, travel is dominated by visits to Cairns, which is unsurprising given what north Queensland has to offer.
Looking a little more closely at the data, we can see the trend of me traveling more, but especially once I started my scientific career. I started at university in 2005, but had a trip to the Europe during my final year of school (2004). This is the first real blip, but things really ramp up during my PhD. studies, where I had a few trips to Europe before moving there. Travel then explodes with attending conferences and holidays, with 2018 likely being the most travel I will ever do in an year. It is sad how well the exponential fit of the data is; but I suspect that my footprint is going to become much smaller into the future: notice that 2020 is flat.
With ridiculously large figures such as those presented, I figured that it might be instructive to recast them. For example, my total travel distance is equivalent to 13.5 times around the world, or 1.4 times to the moon.
With some deeper analysis, it is possible to look at my carbon emissions associated with this amount of flying, and in short, I am responsible for a whopping 62.7 Tonnes. Moreover, breaking this down into short-, medium- and long-haul flights, which have vastly different efficiencies, the percentages were 0.729, 6.13, and 93.1 respectively. So despite long-haul flights being much more efficient, you are by definition traveling a long way, so you emit less carbon dioxide per kilometre, but when you are traveling 20,000 km that does not mean much!
SetDirectory[NotebookDirectory[]] (* Set the working directory to the same directy as the notebook *); data = Import["Flightlist.csv", "Data"] (* Import the dataset containg flights *); headers = 1 (* The number of file headers on in the data file - nominally 1, the column contents *); cleaned = Drop[data, headers] (* Clean the data by dropping the headers *);
To extract the airport locations and create flight paths to draw:
airports = DeleteDuplicates[Flatten[cleaned[[All, 1 ;; 2]]]] (* Make a list of unique airports *); airportloc = AirportData[#, "Coordinates"] & /@ airports (* Apply Airport data to each element of airports *); airportdict = AssociationThread[airports, airportloc] (* Create the association of airports and coordinates *); flightstoplotdest = cleaned[[All, 1 ;; 2]] (* Create a list of flights to plot *); flightstoplotcoords = Map[airportdict[#] &, flightstoplotdest, {2}] (* Use the dictionary with coordinates to construct array of lines to draw *);
To generate the map:
geopoints = {path, PointSize[.0025], Opacity[0.75], Point@GeoPosition@airportloc}(* construct an object containing all airports and point style *); geopath = Style[GeoPath[flightstoplotcoords], Opacity[.15], Thickness[.001], path] (* construct an object containing all flights and specify the line style *); worldmap = {GeoRange -> "World", Frame -> False, ImageSize -> 1920, GeoBackground -> GeoStyling[{"CountryBorders", "Land" -> land, "Ocean" -> water, "Border" -> {Black, Opacity[.2]}}], GeoCenter -> GeoPosition[{0, 150}], GeoProjection -> "Robinson", GeoZoomLevel -> 5}; GeoGraphics[{geopoints, geopath}, worldmap] (* generate the map of the world overlayed with the airports as defined by "geopoints" and flight lines as defined by "geopath" *)
The map generation has some styling defined, but this is obviously personal preference:
path = RGBColor[1/256 {231, 35, 39}]; land = RGBColor[1/256 {174, 217, 236}]; water = RGBColor[1/256 {231, 245, 248}];
For making the map of Australia:
Australia = {-23.6980, 133.8807}; (* Coordinates of the centre of Australia *) auslatlong = {22.5, 25}; (* Extent of latitude and longitude over which to make the map *) ausmap = {GeoRange -> {{Australia[[1]] - auslatlong[[1]], Australia[[1]] + auslatlong[[1]]}, {Australia[[2]] - auslatlong[[2]], Australia[[2]] + auslatlong[[2]]}}, Frame -> False, ImageSize -> 1920, GeoBackground -> GeoStyling[{"CountryBorders", "Land" -> land, "Ocean" -> water, "Border" -> {Black, Opacity[.2]}}], GeoCenter -> GeoPosition[Australia], GeoProjection -> "Robinson", GeoZoomLevel -> 5}; GeoGraphics[{geopoints, geopath}, ausmap] (* generate the map of Australia overlayed with the airports as defined by "geopoints" and flight lines as defined by "geopath" *)
The map of Europe is the same as the map of Australia, except with coordinates
Paris = {48.8566, 2.3522}; (* Coordinates of Paris, France *) eulatlong = {25, 27.5}; (* Extent of latitude and longitude over which to make the map *)
It is worth noting that the final image as shown above was generated by exporting .pdf files of each map, combining them in Adobe Illustrator and then tweaking the colour scheme and exporting as a .jpeg from Adobe Photoshop.