Geographical plotting with matplotlib
¶
To get the features, install the basemap
package using
conda install basemap
and the high res dataset withconda install -c conda-forge basemap-data-hires
.
I ran into multiple conflicts trying to install basemap
in an environment with geopandas
. I was successful in creating a new Python env and installing basemap first.
Thanks to https://jakevdp.github.io/PythonDataScienceHandbook/04.13-geographic-data-with-basemap.html for this tutorial.
In [1]:
Copied!
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
Common steps in plotting with basemap
package¶
- First you set the figure size and other properties of the matplotlib figure
- Next you set the projection using the
Basemap
constructor. You pass the name of the projection from the choice list, a resolution of the built-in dataset to use. Higher res is slower to draw. You pass either the coordinates of lower left & upper right, or coordinates of center. This gives you aBasemap
object which is like an axis. If you are doing a subplot, you can bind it to an existing axes. - On the
Basemap
object, you call the appropriate basemap type - such asetopo()
,bluemarble()
,shadedrelief
etc. and pass appropriate parameters like scale, alpha etc. Scale is not map scale or tiling level, instead it is the factor to scale up or down the rendered image. The default resolution is5400x2700
which is computational intensive. You can pass any additionalimshow
parameters to this call. - If you want to overlay any vectors, you call the
basemap
object like a function and pass the coordinates in lat, lon. The function will return in the appropriate projection system you used to create the object. - Then you use the regular
plt.plot(x,y, symbol_spec)
syntax to plot those points on the map andplt.text(x,y, text_spec)
for labels.
Plot a sphere¶
In [2]:
Copied!
plt.figure(figsize=(8,8))
m = Basemap(projection='ortho', resolution=None, lat_0=35, lon_0=-100)
m.bluemarble(scale=0.6);
plt.figure(figsize=(8,8))
m = Basemap(projection='ortho', resolution=None, lat_0=35, lon_0=-100)
m.bluemarble(scale=0.6);
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
In [10]:
Copied!
type(m)
type(m)
Out[10]:
mpl_toolkits.basemap.Basemap
Let us set the view to India, change figure size and the resolution..
In [11]:
Copied!
plt.figure(figsize=(6,10))
m = Basemap(projection='ortho', resolution=None, lat_0=20.59, lon_0=78.96)
m.bluemarble(scale=0.5);
plt.figure(figsize=(6,10))
m = Basemap(projection='ortho', resolution=None, lat_0=20.59, lon_0=78.96)
m.bluemarble(scale=0.5);
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
In [4]:
Copied!
type(m)
type(m)
Out[4]:
mpl_toolkits.basemap.Basemap
Plot and overlay annotation¶
Plot with a different basemap, using Lambert Conformal Conic projection
In [5]:
Copied!
fig = plt.figure(figsize=(8, 8))
m2 = Basemap(projection='lcc', resolution=None,
width=8E6, height=8E6,
lat_0=45, lon_0=-100,)
m2.etopo(scale=0.5, alpha=0.5)
# Map (long, lat) to (x, y) for plotting
x, y = m2(-122.3, 47.6)
plt.plot(x, y, 'ok', markersize=5)
plt.text(x, y, ' Seattle', fontsize=12);
fig = plt.figure(figsize=(8, 8))
m2 = Basemap(projection='lcc', resolution=None,
width=8E6, height=8E6,
lat_0=45, lon_0=-100,)
m2.etopo(scale=0.5, alpha=0.5)
# Map (long, lat) to (x, y) for plotting
x, y = m2(-122.3, 47.6)
plt.plot(x, y, 'ok', markersize=5)
plt.text(x, y, ' Seattle', fontsize=12);
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
You can even save the map to an image file.
In [13]:
Copied!
fig.savefig('./seattle.png')
plt.imshow(plt.imread('./seattle.png'))
fig.savefig('./seattle.png')
plt.imshow(plt.imread('./seattle.png'))
Out[13]:
<matplotlib.image.AxesImage at 0x7ff67f7b6358>
In [9]:
Copied!
m2()
m2()
Out[9]:
mpl_toolkits.basemap.Basemap
In [7]:
Copied!
y
y
Out[7]:
4518079.266407734
In [8]:
Copied!
type(x)
type(x)
Out[8]:
float
In [9]:
Copied!
%%time
fig = plt.figure(figsize=(8, 8))
m2 = Basemap(projection='lcc', resolution='f',
width=4E5, height=4E5,
lat_0=47, lon_0=-123,)
m2.etopo(scale=1, alpha=0.5)
m2.drawrivers()
m2.drawstates()
m2.drawcounties();
# Map (long, lat) to (x, y) for plotting
# x, y = m2(-122.3, 47.6)
# plt.plot(x, y, 'ok', markersize=5)
# plt.text(x, y, ' Seattle', fontsize=12);
%%time
fig = plt.figure(figsize=(8, 8))
m2 = Basemap(projection='lcc', resolution='f',
width=4E5, height=4E5,
lat_0=47, lon_0=-123,)
m2.etopo(scale=1, alpha=0.5)
m2.drawrivers()
m2.drawstates()
m2.drawcounties();
# Map (long, lat) to (x, y) for plotting
# x, y = m2(-122.3, 47.6)
# plt.plot(x, y, 'ok', markersize=5)
# plt.text(x, y, ' Seattle', fontsize=12);
CPU times: user 18.3 s, sys: 1.16 s, total: 19.5 s Wall time: 19.5 s
Out[9]:
<matplotlib.collections.PolyCollection at 0x7fde5cc98d30>
In [13]:
Copied!
fig = plt.figure(figsize=(8, 8))
m3 = Basemap(projection='cyl', resolution=None,
lat_0=47, lon_0=-123,)
m3.etopo(scale=1, alpha=0.5)
fig = plt.figure(figsize=(8, 8))
m3 = Basemap(projection='cyl', resolution=None,
lat_0=47, lon_0=-123,)
m3.etopo(scale=1, alpha=0.5)
Out[13]:
<matplotlib.image.AxesImage at 0x7fde714675c0>
In [12]:
Copied!
# https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer
m3.arcgisimage(service='NatGeo_World_Map')
# https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer
m3.arcgisimage(service='NatGeo_World_Map')
/Users/atma6951/anaconda3/envs/basemap/lib/python3.6/site-packages/pyproj/crs/crs.py:53: FutureWarning: '+init=<authority>:<code>' syntax is deprecated. '<authority>:<code>' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6 return _prepare_from_string(" ".join(pjargs)) /Users/atma6951/anaconda3/envs/basemap/lib/python3.6/site-packages/pyproj/crs/crs.py:294: FutureWarning: '+init=<authority>:<code>' syntax is deprecated. '<authority>:<code>' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6 projstring = _prepare_from_string(" ".join((projstring, projkwargs)))
Out[12]:
<matplotlib.image.AxesImage at 0x7fde5fc1c6a0>
In [ ]:
Copied!