Geographic Options#
Note
Most of the options below require the GeoViews library to be installed. One notable exception is the tiles
option, which, if the data is in lat/lon coordinates (e.g. GPS data) or already in the Web Mercator coordinate reference system, allows you to overlay the data on a web tiled map without requiring GeoViews.
Supported Plot Types
Only certain plot types support geographic coordinates, currently including: hvplot.hvPlot.points()
, hvplot.hvPlot.paths()
, hvplot.hvPlot.polygons()
, hvplot.hvPlot.image()
, hvplot.hvPlot.quadmesh()
, hvplot.hvPlot.contour()
, and hvplot.hvPlot.contourf()
.
Options for geographic plots, including map projections, tile overlays, and geographic features like coastlines and borders:
Parameters |
Description |
---|---|
coastline (bool, default=False) |
Whether to display a coastline on top of the plot, setting coastline=’10m’/’50m’/’110m’ specifies a specific scale. |
crs (str or int or pyproj.CRS or pyproj.Proj or cartopy.CRS or None) |
Coordinate reference system of the data (input projection) specified as a string or integer EPSG code, a CRS or Proj pyproj object, a Cartopy CRS object or class name, a WKT string, or a proj.4 string. Defaults to PlateCarree. |
features (dict or list or None, default=None) |
A list of features or a dictionary of features and the scale at which to render it. Available features include ‘borders’, ‘coastline’, ‘lakes’, ‘land’, ‘ocean’, ‘rivers’ and ‘states’. Available scales include ‘10m’/’50m’/’110m’. |
geo (bool, default=False) |
Whether the plot should be treated as geographic (and assume PlateCarree, i.e. lat/lon coordinates). |
global_extent (bool, default=False) |
Whether to expand the plot extent to span the whole globe. |
project (bool, default=False) |
Whether to project the data before plotting (adds initial overhead but avoids projecting data when plot is dynamically updated). |
projection (str or int or pyproj.CRS or pyproj.Proj or cartopy.CRS or bool or None) |
Coordinate reference system of the plot (output projection) specified as a string or integer EPSG code, a CRS or Proj pyproj object, a Cartopy CRS object or class name, a WKT string, or a proj.4 string. Defaults to PlateCarree. |
tiles (bool or str or xyzservices.TileProvider or holoviews.Tiles or geoviews.WMTS or None, default=False) |
Whether to overlay the plot on a tile source. If coordinate values fall within
lat/lon bounds, auto-projects to EPSG:3857, unless
|
tiles_opts (dict or None, default=None) |
Options to customize the tiles layer created when |
coastline
#
The coastline
option overlays coastlines on the plot. You can set coastline=True
to use the default scale ('110m'
), or specify one of the available resolution strings: '10m'
, '50m'
, or '110m'
. The dataset originates from Natural Earth.
Enabling this option implies geo=True
and requires GeoViews to be installed.
import hvplot.pandas # noqa
df = hvplot.sampledata.earthquakes("pandas")
plot_opts = dict(x='lon', y='lat', frame_width=250, alpha=0.5)
df.hvplot.points(coastline=True, title="Coastline=True", **plot_opts) +\
df.hvplot.points(coastline='50m', title='Coastline=50m', **plot_opts)
/Users/runner/work/hvplot/hvplot/.pixi/envs/docs/lib/python3.11/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/50m_physical/ne_50m_coastline.zip
warnings.warn(f'Downloading: {url}', DownloadWarning)
crs
#
The crs
option sets the Coordinate Reference System (CRS) of the data (the input/source projection). It accepts a variety of values, including:
cartopy.crs.CRS
instance (e.g.cartopy.crs.PlateCarree
) or class name (e.g.'PlateCarree'
)EPSG code string or integer (e.g.
'EPSG:4326'
,4326
)pyproj.crs.CRS
orpyproj.Proj
instancesPROJ.4 string
WKT string
If not provided, PlateCarree (lat/lon) is assumed when geo=True
.
Enabling this option implies geo=True
and requires GeoViews to be installed.
import hvplot.pandas # noqa
import cartopy.crs as ccrs
import pyproj
df = hvplot.sampledata.earthquakes("pandas")
plot_opts = dict(x='lon', y='lat', coastline=True, frame_width=250, alpha=0.5)
(
df.hvplot.points(crs=ccrs.PlateCarree(), title="cartopy.PlateCarree instance", **plot_opts) +
df.hvplot.points(crs='PlateCarree', title="PlateCarree string", **plot_opts) +
df.hvplot.points(crs='EPSG:4326', title="EPSG:4326 string", **plot_opts) +
df.hvplot.points(crs=pyproj.CRS(4326), title="pyproj.CRS 4326 instance", **plot_opts)
).cols(2)
See also
The projection
option to set the output/target projection.
features
#
The features
option overlays additional geographic features such as land, ocean, rivers, and borders. These features originate from the Natural Earth dataset.
It accepts:
A list of feature names
A dictionary with feature names as keys and resolution strings as values
Available features: 'borders'
, 'coastline'
, 'lakes'
, 'land'
, 'ocean'
, 'rivers'
, 'states'
.
Available scales: '10m'
, '50m'
, '110m'
.
'land'
and 'ocean'
features are underlaid, other features are overlaid.
Important
This option requires a live internet connection to download Natural Earth datasets.
Enabling this option implies geo=True
and requires GeoViews to be installed.
import hvplot.pandas # noqa
df = hvplot.sampledata.earthquakes("pandas")
plot_opts = dict(x='lon', y='lat', frame_width=250, alpha=0.5)
df.hvplot.points(
features=['ocean', 'land'],
title="Features: ocean + land", **plot_opts
) +\
df.hvplot.points(
features={'ocean': '50m', 'land': '50m'},
title="Features with resolution", **plot_opts
)
/Users/runner/work/hvplot/hvplot/.pixi/envs/docs/lib/python3.11/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/110m_physical/ne_110m_ocean.zip
warnings.warn(f'Downloading: {url}', DownloadWarning)
/Users/runner/work/hvplot/hvplot/.pixi/envs/docs/lib/python3.11/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/110m_physical/ne_110m_land.zip
warnings.warn(f'Downloading: {url}', DownloadWarning)
/Users/runner/work/hvplot/hvplot/.pixi/envs/docs/lib/python3.11/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/50m_physical/ne_50m_ocean.zip
warnings.warn(f'Downloading: {url}', DownloadWarning)
/Users/runner/work/hvplot/hvplot/.pixi/envs/docs/lib/python3.11/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/50m_physical/ne_50m_land.zip
warnings.warn(f'Downloading: {url}', DownloadWarning)
geo
#
The geo
option declares that the plot is geographic and enables plotting with GeoViews, which is required to be installed.
When geo=True
and without further definition, the input data is assumed to be in lat/lon coordinates. When not set explicitly, the data_aspect
option is set to 1
.
import hvplot.pandas # noqa
df = hvplot.sampledata.earthquakes("pandas")
plot_opts = dict(x='lon', y='lat', frame_width=250, alpha=0.5)
plot = df.hvplot.points(title="geo=False", **plot_opts)
plot_geo = df.hvplot.points(geo=True, title="geo=True", **plot_opts)
(plot + plot_geo).opts(shared_axes=False)
The object returned by the df.hvplot.points()
call is a GeoViews Points
element.
type(plot_geo)
geoviews.element.geo.Points
global_extent
#
The global_extent
option expands the plot extent to span the full globe. This is useful when your data covers only part of the globe, but you still want to display the full world extent.
Enabling this option implies geo=True
and requires GeoViews to be installed.
import hvplot.pandas # noqa
df = hvplot.sampledata.earthquakes("pandas")
df.hvplot.points(
x='lon',
y='lat',
frame_height=200,
global_extent=True,
coastline=True,
title="Global Extent Enabled"
)
project
#
The project
option projects the data to the output/target projection before applying operations enabled by the datashade
or rasterize
options. This can greatly improve interactivity when one of these operations is enabled, avoiding to re-project the data when panning/zooming.
Enabling this option implies geo=True
and requires GeoViews to be installed.
projection
#
The projection
option sets the display CRS of the plot (the output/target projection).
Accepts the same values as crs
, including:
cartopy.crs.CRS
instance (e.g.cartopy.crs.PlateCarree
) or class name (e.g.'PlateCarree'
)EPSG code string or integer (e.g.
'EPSG:4326'
,4326
)pyproj.crs.CRS
orpyproj.Proj
instancesPROJ.4 string
WKT string
If not specified, defaults to PlateCarree, or to Web Mercator when tiles=True
.
Enabling this option implies geo=True
and requires GeoViews to be installed.
import cartopy.crs as ccrs
import hvplot.pandas # noqa
df = hvplot.sampledata.earthquakes("pandas")
plot_opts = dict(x='lon', y='lat', coastline=True, alpha=0.5)
layout = df.hvplot.points(
frame_width=250,
geo=True,
global_extent=True,
title='Default display CRS: PlateCarree',
**plot_opts
) +\
df.hvplot.points(
frame_width=200,
projection=ccrs.Orthographic(125, 0),
global_extent=True,
title='Orthographic Projection',
**plot_opts
) +\
df.hvplot.points(
frame_height=250,
projection='EPSG:32651',
title='UTM 51N',
**plot_opts
)
layout.opts(shared_axes=False)
See also
The crs
option to define the source CRS.
tiles
#
Tip
This option can be used without having to install GeoViews to plot data in lat/lon or Web Mercator coordinates.
The tiles
option adds a tiled web map, or tile map, as a basemap layer. It accepts:
True
: defaults to the OpenStreetMap layerxyzservices.TileProvider
instance (e.g.xyz.Esri.WorldPhysical
). Thexyzservices
library gives easy access to hundreds of tiled web maps.HoloViews/GeoViews tile name strings (e.g.
'EsriTerrain'
). See the list below of tiles available as a stringholoviews.Tiles
class or instance (e.g.hv.element.tiles.CartoDark
)geoviews.WMTS
class or instance (e.g.gv.tile_sources.CartoDark
)
Important
This option requires a live internet connection to download the web tiles on the fly (zooming/panning).
When tiles
is enabled, the target projection
is internally set to Web Mercator (EPSG:3857
) as this is the only projection supported by tiled web maps.
hvPlot can display the data overlaid on a tile map without having to set geo=True
and rely on GeoViews:
If the data is already in the Web Mercator CRS (easting (X) /northing (Y) metric units), as no projection is needed.
If the coordinate values fall within lat/lon bounds, the data is auto-projected (except for lazy data objects) to Web Mercator. This behavior can be disabled by setting the
projection
toFalse
.
import geoviews as gv
import holoviews as hv
print("HoloViews tiles:", *hv.element.tiles.tile_sources, sep=" ", end="\n\n")
print("GeoViews tiles:", *gv.tile_sources.tile_sources, sep=" ")
HoloViews tiles: CartoDark CartoLight EsriImagery EsriNatGeo EsriUSATopo EsriTerrain EsriStreet EsriReference OSM OpenTopoMap
GeoViews tiles: CartoDark CartoEco CartoLight CartoMidnight EsriImagery EsriNatGeo EsriUSATopo EsriTerrain EsriReference EsriOceanBase EsriOceanReference EsriWorldPhysical EsriWorldShadedRelief EsriWorldTopo EsriWorldDarkGrayBase EsriWorldDarkGrayReference EsriWorldLightGrayBase EsriWorldLightGrayReference EsriWorldHillshadeDark EsriWorldHillshade EsriAntarcticImagery EsriArcticImagery EsriArcticOceanBase EsriArcticOceanReference EsriWorldBoundariesAndPlaces EsriWorldBoundariesAndPlacesAlternate EsriWorldTransportation EsriDelormeWorldBaseMap EsriWorldNavigationCharts EsriWorldStreetMap OSM OpenTopoMap
First we’ll set geo=True
together with tiles
to enable plotting with GeoViews.
import geoviews as gv
import hvplot.pandas # noqa
import xyzservices.providers as xyz
df = hvplot.sampledata.earthquakes("pandas")
plot_opts = dict(geo=True, x='lon', y='lat', alpha=0.2, c='brown', frame_width=250)
layout = (
df.hvplot.points(tiles=True, title="Default to OpenStreetMap", **plot_opts) +
df.hvplot.points(tiles=xyz.Esri.WorldPhysical, title="xyz.Esri.WorldPhysical", **plot_opts) +
df.hvplot.points(tiles='EsriTerrain', title="EsriTerrain string", **plot_opts) +
df.hvplot.points(tiles=gv.tile_sources.EsriImagery, title="GeoViews WMTS", **plot_opts)
)
layout.cols(2)
We now create the same plots but without geo=True
. The dataset contains lat/lon coordinates, that hvPlot will automatically project to Web Mercator.
import holoviews as hv
import hvplot.pandas # noqa
import xyzservices.providers as xyz
df = hvplot.sampledata.earthquakes("pandas")
plot_opts = dict(x='lon', y='lat', alpha=0.2, c='brown', frame_width=250)
layout = (
df.hvplot.points(tiles=True, title="Default: OpenStreetMap", **plot_opts) +
df.hvplot.points(tiles=xyz.Esri.WorldPhysical, title="xyz.Esri.WorldPhysical", **plot_opts) +
df.hvplot.points(tiles='EsriTerrain', title="EsriTerrain string", **plot_opts) +
df.hvplot.points(tiles=hv.element.tiles.EsriImagery, title="HoloViews Tiles", **plot_opts)
)
layout.cols(2)
Tip
When dealing with large datasets meant to be overlaid on a tile map, it may be appropriate to project them to Web Mercator beforehand. HoloViews provides a simple utility function to convert lat/lon coordinates to Web Mercator northing/easting metric values. See the example below.
import hvplot.pandas # noqa
from holoviews.util.transform import lon_lat_to_easting_northing
df = hvplot.sampledata.earthquakes("pandas")
df['x'], df['y'] = lon_lat_to_easting_northing(df['lon'], df['lat'])
print(df[['lat', 'lon', 'x', 'y']].head(2))
df.hvplot.points(x='x', y='y', alpha=0.2, c='brown', frame_width=250, tiles=True)
lat lon x y
0 -5.7711 112.6357 1.253855e+07 -643524.978512
1 5.6918 126.5299 1.408524e+07 634652.990242
GeoPandas GeoDataFrame objects can also be overlaid on a tile map without GeoViews, like in the example below, where a dataset in the UTM 51N CRS is plotted (hvPlot internally converting the data to Web Mercator).
import geopandas as gpd
import hvplot.pandas # noqa
df = hvplot.sampledata.earthquakes("pandas")
gdf = gpd.GeoDataFrame(
df,
geometry=gpd.points_from_xy(df['lon'], df['lat']),
crs="EPSG:4326"
).to_crs("EPSG:32651") # UTM 51N
gdf.hvplot.points(alpha=0.2, c='brown', frame_width=250, tiles=True)
tiles_opts
#
The tiles_opts
option is a dictionary of style properties applied to the tiles layer. Requires tiles
to be set.
Common keys include: alpha
, width
, height
, etc.
import hvplot.pandas # noqa
df = hvplot.sampledata.earthquakes("pandas")
df.hvplot.points(
x='lon', y='lat', frame_width=300, c='mag',
tiles=True, tiles_opts={'alpha': 0.3},
title="Tile Layer with Alpha"
)