Geographic Data#

import xarray as xr
import hvplot.pandas  # noqa
import hvplot.xarray  # noqa
import as ccrs

from bokeh.sampledata.airport_routes import airports


The plot API also has support for geographic data built on top of Cartopy and GeoViews. Both can be installed using conda with:

conda install geoviews

or with pip:

pip install geoviews


Only certain hvPlot types support geographic coordinates, currently including: ‘points’, ‘polygons’, ‘paths’, ‘image’, ‘quadmesh’, ‘contour’, and ‘contourf’. As an initial example, consider a dataframe of all US airports (including military bases overseas):

AirportID Name City Country IATA ICAO Latitude Longitude Altitude Timezone DST TZ Type source
0 3411 Barter Island LRRS Airport Barter Island United States BTI PABA 70.134003 -143.582001 2 -9 A America/Anchorage airport OurAirports
1 3413 Cape Lisburne LRRS Airport Cape Lisburne United States LUR PALU 68.875099 -166.110001 16 -9 A America/Anchorage airport OurAirports
2 3414 Point Lay LRRS Airport Point Lay United States PIZ PPIZ 69.732903 -163.005005 22 -9 A America/Anchorage airport OurAirports

Plotting points#

If we want to overlay our data on geographic maps or reproject it into a geographic plot, we can set geo=True, which declares that the data will be plotted in a geographic coordinate system. The default coordinate system is the PlateCarree projection, i.e., raw longitudes and latitudes. If the data is in another coordinate system, you will need to declare an explicit crs as an argument, in which case geo=True is assumed. Once hvPlot knows that your data is in geo coordinates, you can use the tiles option to overlay a the plot on top of map tiles.

airports.hvplot.points('Longitude', 'Latitude', geo=True, color='red', alpha=0.2,
                       xlim=(-180, -30), ylim=(0, 72), tiles='ESRI')

Declaring a CRS#

To declare a geographic plot we have to supply a (or coordinate reference system). Coordinate reference systems are described in the GeoViews documentation and the full list of available CRSs is in the cartopy documentation.


Since a GeoPandas DataFrame is just a Pandas DataFrames with additional geographic information, it inherits the .hvplot method. We can thus easily load shapefiles and plot them on a map:

import geopandas as gpd

cities = gpd.read_file(gpd.datasets.get_path('naturalearth_cities'))

cities.hvplot(global_extent=True, frame_height=450, tiles=True)

The GeoPandas support allows plotting GeoDataFrames containing 'Point', 'Polygon', 'LineString' and 'LineRing' geometries, but not ones containing a mixture of different geometry types. Calling .hvplot will automatically figure out the geometry type to plot, but it also possible to call .hvplot.points, .hvplot.polygons, and .hvplot.paths explicitly.

To draw multiple GeoDataFrames onto the same plot, use the * operator:

world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))

world.hvplot(geo=True) * cities.hvplot(geo=True, color='orange')

It is possible to declare a specific column to use as color with the c keyword:

world.hvplot(geo=True) + world.hvplot(c='continent', geo=True)


Spatialpandas is another powerful library for working with geometries and is optimized for rendering with datashader, making it possible to plot millions of individual geometries very quickly:

import spatialpandas as spd

spd_world = spd.GeoDataFrame(world)

spd_world.hvplot(datashade=True, project=True, aggregator='count_cat', c='continent', color_key='Category10')