PyMappr is a remake of SimpleMappr as an offline desktop application, written in Python. Load a table of localities, style the points, and export a map ready for a paper.
Get the latest build for your platform from the
releases page. A new release is built each time a pull
request is merged into main.
| Platform | File | Install |
|---|---|---|
| Windows | PyMappr-Setup-<version>.exe |
Run the installer |
| macOS | PyMappr-<version>-macOS.dmg |
Open and drag to Applications |
| Linux (Ubuntu) | pymappr_<version>_amd64.deb |
sudo apt install ./pymappr_<version>_amd64.deb |
| Linux (Fedora) | pymappr-<version>-1.<dist>.x86_64.rpm |
sudo dnf install ./pymappr-<version>-*.x86_64.rpm |
| Linux (Arch) | pymappr-<version>-1-x86_64.pkg.tar.zst |
sudo pacman -U pymappr-<version>-1-x86_64.pkg.tar.zst |
| Any Linux | PyMappr-<version>-linux-<distro>-x86_64.tar.gz |
Extract and run PyMappr/PyMappr |
The Releases tab is the only official download source.
Requires Python 3.11+ with Tk support.
pip install -r requirements.txt
python scripts/fetch_data.py # one-time data download (~165 MB core;
# add --skip-extras to skip biodiversity/ecoregion overlays)
python -m pymappr- Load points from CSV, TSV or Excel. Every import starts with a column-mapping step, so the columns can be in any order.
- Type points in by hand, in decimal degrees or DMS, or click to place them on the map.
- Group, color or shape points by any name column. Two attributes at once (e.g. color by Family, symbol by Genus) give a compact legend.
- Open symbols for chosen rows: with Type status = Holotype, type localities draw as the outline of their species' symbol, and a legend row says what the open symbols mark.
- Palettes: the default, a colourblind-safe one (Okabe-Ito), and black & white with a settable point outline for outlined markers.
- Legend position, columns, marker scale and spacing, with bold, italic or underline for the labels and title. Customize legend renames, hides, reorders and restyles individual rows.
- Presets save every setting except your data and zoom, to apply to any other project in one click. The built-in Standard preset sets up a journal figure (see below).
- About 30 Natural Earth layers you can switch on and off (borders, cities, water, physical features, infrastructure). Detail switches between 110m, 50m and 10m as you zoom.
- Six map projections, a Globe (orthographic) view you can drag to spin, and regional Lambert projections, all reprojected live.
- Continent presets, a graticule, a compass, and a legend and labels you can drag into place.
- A geodesically measured scale bar in kilometres, miles or both, with corner, segmented or plain styling, an automatic or fixed length, and drag-to-place. The north arrow takes the same placement controls.
- An inset map in any corner. As a locator it shows the state, country, continent or world around the map, with a box marking the area the map covers. As a close-up it shows an area too small to see on the map (Hawaii on a world map, say), and the box goes on the map instead. Pick the inset's projection (a globe turned to face the map is one choice), its layers and whether it shows your points. Use current view sets a close-up's area: zoom in on it, click, and zoom back out.
- Landscape or portrait framing. The New Zealand, Madagascar and Florida maps in the gallery are portrait.
More examples, including bathymetry, boundaries, time zones, and basemap
renders, are in docs/images/.
- Save the map as PNG, JPEG, TIFF, PDF, SVG or WebP at the DPI you choose, as on screen or at a print width (17 cm for a Zootaxa / Phytotaxa page, 8 cm for one column, or any width in cm), so text prints at its point size. TIFFs are LZW-compressed and greyscale when the map has no colour; PDF and SVG text stays editable.
- Export it as a self-contained Python (matplotlib) or R (ggplot2) script
that redraws it, inset map included, outside PyMappr. Run the script with
--install-depsto have it install what it needs. - Projects (
.pymapprfiles) save your datasets and settings, with autosave/restore, and export/import for sharing.
- Data tab > Combine columns... joins Genus and Species into one name column and groups by it, so each legend line reads Eleusis chapadensis. The source file is left as it is.
- Data tab > Presets, choose Standard and click Apply. It sets the map up for Zootaxa, Phytotaxa and similar journals: black & white points with black outlines and varied shapes, a plain boxed legend with italic names sorted A-Z, shaded by genus and without a heading (unless you typed one), holotypes as open symbols when a Type status column names them, and export at 600 DPI and 17 cm wide. Datasets with no Color by are colored by the parent name column, and a legend order you set by hand is kept. Rows you restyled with Customize legend keep their styling. Adjust anything else, then Save current as... to keep it as your own preset.
- File > Save map as... and pick TIFF or PDF. A 600-DPI black & white TIFF comes out greyscale and LZW-compressed, well under the 2 MB at which Zootaxa asks for JPEG instead.
The settings in each map below suit its data, and every map has a
labelled grid. The localities are generated for illustration, not real
records. They are in sample_data/gallery/ if you
want to try them.
You can ask a chatbot to draw a distribution map, and it may draw a good one. Ask again with the same data and the same prompt, though, and you will usually get a different map. Large language models are non-deterministic: their output varies from run to run, and the model behind a chat service can change without notice. A figure made that way cannot be reproduced exactly, which matters when it has to hold up through revisions and replication.
PyMappr draws the same map from the same data and settings every time. There is no sampling step, so the inputs fully describe the figure:
- Save the map as a project (
.pymappr) and reopen it later to get the same map, or send it to a co-author. - Export a Python or R script that redraws the map without PyMappr, and archive it with your data or include it as supplementary material.
- Every release stays on the releases page. If a reviewer asks for a change a year from now, install the version you used (shown under Help > About PyMappr) and you are back where you were. Give that version number in your methods section.
Any number of name columns followed by Longitude/Latitude, in any order. You confirm the mapping on import.
| Genus | Species | Longitude | Latitude |
|---|---|---|---|
| Eleusis | chapadensis | -68.4349 | -12.3541 |
| Xanthopygus | orinocensis | 67°33'37"W | 10°18'29"N |
With Genus and Species in separate columns like this, Combine columns... on the Data tab puts both on one legend line without editing the file:
sample_data/ has sample datasets for beetles, hornbills,
seabirds, and orchids.
MiniMappr is a browser-only edition of PyMappr at
calebhendren.github.io/PyMappr. It
covers the core workflow with nothing to install. Its source is on the
minimappr branch
of this repository, which GitHub Pages serves.
python -m pytest tests/ # the test suite (a few tests need the map data)
python scripts/make_screenshots.py # regenerate the README map images
python scripts/make_screenshots.py --out preview --all # render check, more layers
python scripts/make_app_screenshot.py # the app screenshots (needs a display)Project layout:
pymappr/files/coords.py- decimal/DMS coordinate parsingpymappr/files/data_loader.py- CSV/TSV/Excel reading and column mappingpymappr/files/projects.py- project files, settings, session autosavepymappr/geo/layers.py- Natural Earth layer store and on-disk frame cachepymappr/geo/projections.py- map projections (pyproj)pymappr/renderer/- matplotlib map rendering, one module per concern (view, layers, overlays, labels, points and legend, mouse, blit), plus the layer style tables shared with code exportpymappr/styling/styles.py- point styles and group/color-by stylingpymappr/styling/legend.py- legend options and legend rowspymappr/styling/decorations.py- scale bar and compass optionspymappr/styling/layout.py- what every dataset draws (shared by the app and code export)pymappr/export/- Python/R code export:codegen.pyis the entry point,config.pyandlayers_config.pycollect the map settings,python_script.pyandr_script.pywrite the scripts, andtemplates/holds the drawing code every exported script ends withpymappr/updates.py- daily update check against the GitHub releases APIpymappr/app.py- the main window, put together from the handler mixins inpymappr/handlers/(project files, state, datasets, presets, map settings)pymappr/ui/- Tkinter dialogs, andui/control_panel/for the tabbed control panel (one module per tab, plus its tables and widget builders)scripts/fetch_data.py- downloads and prepares the bundled map datapackaging/- PyInstaller spec, Inno Setup script, Linux/Fedora/Arch packaging
Building the release packages is automated by
build-release.yml; see
packaging/ for local build scripts per platform.
If PyMappr is useful to you, you can support its development on Ko-fi: ko-fi.com/calebhendren
Citing PyMappr is not necessary, but it is welcome:
Hendren, Caleb. PyMappr [computer software]. https://github.com/CalebHendren/PyMappr https://doi.org/10.5281/zenodo.21522496
Map data from Natural Earth (public
domain). The optional Biodiversity & ecoregions overlays (Terrestrial
ecoregions from RESOLVE Ecoregions 2017,
Biodiversity hotspots from Conservation International, 2016.1,
and Marine ecoregions from WWF/TNC MEOW)
are CC-BY licensed and fetched by scripts/fetch_data.py. If a source is
unavailable, that layer is skipped and the rest of PyMappr works as usual.
















