My wife and I were recently tackling the overdue task of finishing some photo albums. I was hunting the web for a simple way to create easily some beautiful maps, showing where we have been. My hunt left me unsatisfied, so I dug out my old Basemap example, and tweaked it to yield the desired figures.
I created a travelmaps
-function which adjusts some settings and provides the three functions country
, city
, and arrow
. The settings consist of a tweaked version of the xkcd-style, the colour-cycle from Bayesian Methods for Hackers, and setting the figure.dpi
and savefig.dpi
to the same value, so the on-screen figures look like the saved pdfs.
The function country
is an adapted version from a blogpost by Thomas Lecocq. It plots a country, or a list of countries, with given face- and edge-colours on a given basemap, where I got the country shapefiles from Global Administrative Areas (gadm.org).
The other two functions, city
and arrow
, are simply matplotlib
-plot
and -annotate
functions, to plot cities and connect them with arrows.
import travelmaps as tm
from adashof import cm2in
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
(You can find the two functions travelmaps
and adashof
in my GitHub repo.)
Global Map
This first example is a global map, where a number of countries is highlighted.
fig_g = plt.figure(figsize=(cm2in([12, 8])))
# Create basemap
m_g = Basemap(resolution='i', projection='robin', lon_0=0)
# Make continents grey, and oceans slighty blue
m_g.drawlsmask(land_color='.8', ocean_color='#f7fbff')
m_g.drawcoastlines(color='.8', linewidth=.1)
m_g.drawcountries(color='.8', linewidth=.1)
# Fill visited countries
countries = ['CHN', 'CHE', 'DNK', 'TUR', 'MEX', 'HUN', 'ISL', 'BGR', 'GRC', 'FRA',
'SVK', 'NOR', 'CZE', 'AUT', 'DEU', 'GBR', 'MAR', 'SRB', 'USA',]
tm.country(countries, m_g)
#plt.savefig('plots/World.png', bbox_inches='tight', pad_inches=0.02)
plt.show()
East Europe Trip
The second example is a local map with several visited countries. Here, the drawlsmask
and drawcountries
functions of basemap
do not yield a satisfying result. I therefore plot the visited as well as the not visited countries with tm.countries
, the former in colour and the latter grey.
fig_e = plt.figure(figsize=(cm2in([8, 8])))
# Cities
BUD = [47.4925, 19.051389] # Budapest
SOF = [42.7, 23.333333] # Sofia
IST = [41.013611, 28.955] # Istanbul
PRA = [50.083333, 14.416667] # Prague
BEL = [44.816667, 20.466667] # Belgrade
DRE = [51.033333, 13.733333] # Dresden
BER = [52.516667, 13.383333] # Berlin
# Create basemap
m_e = Basemap(width=2200000, height=2200000, resolution='c',
projection='tmerc', lat_0=BUD[0], lon_0=BEL[1])
# Fill non-visited countries (fillcontinents does an unsatisfying job)
countries = ['AUT', 'CHE', 'FRA', 'DNK', 'SVK', 'GRC', 'ALB',
'ITA', 'LIE', 'POL', 'ROU', 'SVN', 'BEL', 'HRV',
'TUN', 'NLD', 'RUS', 'SWE', 'LUX', 'BLR', 'LTU',
'EST', 'LVA', 'UKR', 'MDA', 'DZA', 'BIH', 'KO-',
'MKD', 'MNE',]
tm.country(countries, m_e, fc='.8', ec='.5', lw=.2)
# Fill visited countries
visited = ['TUR', 'BGR', 'SRB', 'HUN', 'CZE', 'DEU',]
tm.country(visited, m_e, ec='b', lw=.5)
# Add cities
offs = [0, .4]
tm.city(BER, 'Berlin', m_e, offs=offs)
tm.city(DRE, 'Dresden', m_e, offs=offs)
tm.city(PRA, 'Prague', m_e, offs=offs)
tm.city(IST, 'Istanbul', m_e, offs=offs)
tm.city(BEL, 'Belgrade', m_e, offs=offs)
tm.city(SOF, 'Sofia', m_e, offs=offs)
tm.city(BUD, 'Budapest', m_e, offs=offs)
# Connect with arrows
tm.arrow(IST, SOF, m_e)
tm.arrow(SOF, BEL, m_e)
tm.arrow(BEL, BUD, m_e)
tm.arrow(BUD, PRA, m_e)
tm.arrow(PRA, DRE, m_e)
tm.arrow(DRE, BER, m_e)
#plt.savefig('plots/EastEurope.png', bbox_inches='tight', pad_inches=0.02)
plt.show()
Scotland
This last examples is another local map one, with only one country this time.
fig_s = plt.figure(figsize=(cm2in([8, 8])))
# Cities
EDI = [55.953056, -3.188889] # Edinburgh
JOG = [58.64, -3.07] # John o' Groats
ABD = [57.1526, -2.11] # Aberdeen
INV = [57.4718, -4.2254] # Inverness
SCR = [58.609722, -3.5525] # Scrabster
STR = [58.96, -3.3] # Stromness
ULL = [57.9, -5.166] # Ullapool
STO = [58.209, -6.387] # Stornoway
TAR = [57.897749, -6.800595] # Tarbert
UIG = [57.586, -6.357] # Uig
EID = [57.274028, -5.516111] # Eilean Donan
# Create basemap
m_s = Basemap(width=500000, height=500000, resolution='c',
projection='tmerc', lat_0=57.65, lon_0=-4.5)
# Fill country
tm.country('GBR', m_s, fc='g', ec='b', lw=.1)
# Add cities
tm.city(EDI, 'Edinburgh', m_s)
tm.city(ABD, 'Aberdeen', m_s)
tm.city(JOG, "John o' Groats", m_s)
tm.city(SCR, '', m_s, halign='right')
tm.city(STR, 'Orkney Islands', m_s, halign='right')
tm.city(ULL, 'Ullapool', m_s)
tm.city(STO, '', m_s)
tm.city(TAR, 'Outer Hebrides', m_s, offs=[-.4, .1], halign='center')
tm.city(UIG, '', m_s)
tm.city(EID, 'Eilean Donan', m_s, offs=[.1, -.2], halign='right')
# Connect with arrows
tm.arrow(EDI, ABD, m_s, fc='r')
tm.arrow(ABD, JOG, m_s, fc='r', rad=-1.2)
tm.arrow(JOG, SCR, m_s, fc='r')
tm.arrow(SCR, STR, m_s, fc='r', rad=.4)
tm.arrow(STR, SCR, m_s, fc='r', rad=.4)
tm.arrow(SCR, ULL, m_s, fc='r', rad=.5)
tm.arrow(ULL, STO, m_s, fc='r')
tm.arrow(STO, TAR, m_s, fc='r', rad=.5)
tm.arrow(TAR, UIG, m_s, fc='r')
tm.arrow(UIG, EID, m_s, fc='r', rad=.3)
tm.arrow(EID, EDI, m_s, fc='r', rad=.3)
#plt.savefig('plots/Scotland.png', bbox_inches='tight', pad_inches=0.02)
plt.show()
These are just three examples to show the possibilities. You can find the complete notebooks travelmaps.ipynb and Travel.ipynb with more examples on my GitHub page in the blog-notebooks-repo.