Plotting with PROJ and Matplotlib.
Project description
FlotteKarte
FlotteKarte is a Python library for quick and versatile cartography based on PROJ4-string syntax and using Matplotlib, NumPy, and PyPROJ under the hood.
Installing
The install system is based on the Meson build system and Python setuptools. A typical install might be performed by executing the following command within this project directory:
pip install --user .
At first import of flottekarte
, the Meson build system will be invoked to
compile the backend. Similarly, whenever importing the backend fails (e.g. if
the system PROJ library was updated) the backend is recompiled. For this reason,
FlotteKarte needs to be installed with write permissions (i.e. user install).
Requirements
The following software has to be installed:
- PROJ
- OpenMP
- NumPy
- Matplotlib
- PyProj
- SciPy
- Meson
- Ninja
The following software will be automatically downloaded during Meson installation:
Recompiling the backend after an update to PROJ
If the system's PROJ library is updated, FlotteKarte might be linked to a shared library that is no longer available on the system. Recompiling FlotteKarte will be necessary. This will automatically be performed at import time if a failure to load the shared library is detected.
For this reason, Meson and Ninja need to be available on the system if the PROJ library that FlotteKarte is linked to changes.
If this package should be packaged for some system package manager, the file
flottekarte/extensions/cdll.py
would have to be adjusted, see comments
therein.
Usage
FlotteKarte is a low-overhead plotting routine. The conceptual idea behind this package is that a map is fully defined through the 2D cartesian coordinates that result from applying the map projection to different geographical data. For displaying data on a two-dimensional canvas, Matplotlib is a powerful tool. Conversion between geographic and projected coordinates can easily be done using PyProj. The gap between these two powerful tools and a polished map lies in potential difficulties when translating spherical line topology to 2D cartesian space, and by introducing typical map decorations such as grids or ticks. FlotteKarte aims to fill this gap with a simple interface.
FlotteKarte's philosophy is to work completely within the 2D projected coordinates,
that is, very close to the projected data. If projected coordinates of data can be
obtained, the data can be drawn directly on the underlying Matplotlib Axes. The
Map
class can then be used to add typical map decoration to that axes using information
that it derives from the numerics of the PROJ projection.
The basic usage pattern is:
# Given:
# lon: some longitudes
# lat: some latitudes of equal size
# proj_str: A PROJ4 string
import matplotlib.pyplot as plt
from flottekarte import Map
from pyproj import Proj
fig = plt.figure()
ax = fig.add_subplot(111)
# Project the data:
x,y = Proj(proj_str)(lon,lat)
# Create a map on axis 'ax' from the PROJ string.
# Alternative:
# mp = Map(proj_str, ax, xlim, ylim)
# where xlim and ylim would be determined through x and y.
mp = Map.for_data(lon, lat, proj_str, ax)
# Scatter the data:
ax.scatter(x,y)
# ... and maybe some other here.
# Plot a grid with 5 degree spacing:
mp.plot_grid(5)
# Complete the plot by this call (ticks every 5 degrees).
mp.plot_axes(5)
Example Map for Iceland
This code uses the file testing/data/natura-learth/iceland.geojson
to show
the coast line of iceland and compute, in a stereographic projection, the
distance to shoreline:
import numpy as np
import matplotlib.pyplot as plt
from flottekarte import Map, GeoJSON
from pyproj import Proj
from scipy.spatial import KDTree
# The projection we will be working in:
proj_str = '+proj=stere +lon_0=-18 +lat_0=64.5'
proj = Proj(proj_str)
# Load the shoreline (this assumes the GeoJSON is
# in the same folder):
iceland = GeoJSON('iceland.geojson', proj_str)
xlim, ylim = iceland.get_extent()
# Extract the vertices from the PatchCollection:
iceland_xy = [patch.vertices for patch in
iceland.get_polygon_patches()
.get_paths()][0]
# Interpolate the distance to the shoreline
# on a grid:
xg, yg = np.meshgrid(np.linspace(*xlim, 120),
np.linspace(*ylim, 80))
zg = np.empty(xg.shape)
tree = KDTree(iceland_xy)
zg.flat[...] = tree.query(np.stack((xg.flat, yg.flat),
axis=1))[0]
# Compute the locations of local distance maxima:
maxima = np.zeros(zg.shape, dtype=bool)
maxima[1:-1,1:-1] = (zg[:-2,1:-1] < zg[1:-1,1:-1]) \
& (zg[2:,1:-1] < zg[1:-1,1:-1]) \
& (zg[1:-1,:-2] < zg[1:-1,1:-1]) \
& (zg[1:-1,2:] < zg[1:-1,1:-1])
xmaxima = xg[maxima]
ymaxima = yg[maxima]
# Finally, after processing create the map:
fig = plt.figure(dpi=100, figsize=(12.80, 6.40))
ax = fig.add_subplot(111)
mp = Map(proj_str, ax, xlim, ylim, proj=proj)
mp.add_data(iceland, color='navajowhite')
ax.contour(xg, yg, zg, colors='k',
linewidths=0.8)
ax.scatter(xmaxima, ymaxima, marker='.', color='k',
s=5)
mp.plot_axes(2)
fig.savefig('iceland-example-map.png')
The map should look like the following:
Documentation
For further documentation, visit the FlotteKarte documentation
Citation
If you use FlotteKarte in your scientific publication, please consider citing it with the following citation:
Ziebarth, Malte Jörn (2022): FlotteKarte - a Python library for quick and versatile cartography based on PROJ4-string. GFZ Data Services. https://doi.org/10.5880/GFZ.2.6.2022.003
You can also consider adding the version tag you used.
License
This software is licensed under the European Public License (EUPL) version 1.2 or later.
Changelog
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.2.9] - 2023-08-19
Changed
- Work on Github actions.
- Documentation updates.
- Metadata updates.
[0.2.8] - 2023-08-19
Changed
- Reorganized the build system of the compiled backend. Use
recompile_flottekarte()
as default compilation mechanism.
[0.2.7] - 2023-08-18
Added
- Check for the existence of a
type=crs
argument in the PROJ string, which leads toObject is not a coordinate operation
under the hood, and raise errors if detected.
[0.2.6] - 2023-01-03
Added
- Add Meson build option 'portable' to disable native tuning of the binaries.
[0.2.5] - 2022-11-30
Added
- Add missing COPYING file.
[0.2.4] - 2022-11-30
Added
GeoJSON
now uses the matplotlib_path
facility to crop polygons to map extents. This is useful for reducing the file size when looking at small coast segments of detailed continental polygons.
Changed
- When determining
lon_0
of global projection strings, guard against unspecified default values.
[0.2.3] - 2022-08-14
Added
- Guard against non-identical version numbers across the project.
- Outsource the
flottekarte
shared object loading check to a subprocess - Automatic recompilation of the shared object if loading fails.
[0.2.2] - 2022-08-05
Added
- Github pages setup.
Changed
- Use
https
by default for ProjWrapCpp subproject.
[0.2.1] - 2022-08-05
Added
- Finalized first documentation.
Changed
- Rename compiled extension from
libinverse
tolibflottekarte
- More informative error messages when importing
libflottekarte
fails. - More typing information.
[0.2.0] - 2022-08-04
Added
- Added automatic extent computation for some global projections.
- Coordinate labels can be rotated with axis orientation.
- Add AugmentedProj class that automatically falls back to numerical inversion if a projection does not come with a defined inversion routine.
Changed
- Simplified detection of discontinuities in path processing.
- Reworked the map boundary. It can now follow non-rectangular map shapes as defined by violated bijectivity of the map projection.
- Reworked the axes labelling mechanism. Axes are removed if they overlapped, based on a weighting criterion, and the labels now follow the (potentially non-rectangular) map boundary polygon.
- Fix various bugs.
[0.1.0] - 2022-06-30
Added
- First version
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file flottekarte-0.2.9.tar.gz
.
File metadata
- Download URL: flottekarte-0.2.9.tar.gz
- Upload date:
- Size: 245.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3c78147769e3447b79d90ec7d8bc04ee5b56b683424a4b4e789ed2e8f7a080e4 |
|
MD5 | 42ddc48c39983d988ce71094d92a786d |
|
BLAKE2b-256 | 70acc47199c212d2930472bf84929a234cef369c4084f19d0e139b909316afcb |
File details
Details for the file flottekarte-0.2.9-py3-none-any.whl
.
File metadata
- Download URL: flottekarte-0.2.9-py3-none-any.whl
- Upload date:
- Size: 86.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0ded62e12176fa3aa8f11a5fa7c378f584adf4236bcda022fa03cba32875833b |
|
MD5 | 62746fe5973abf7bb92c1b0d6b0a09cb |
|
BLAKE2b-256 | e3a248fa737a0e4a22e4e442f12046bf863e48285369be55c250f70fc8bc04e5 |