Files
Marcelo de Oliveira Rosa Prates 3ef70792e2 Replace tutorial notebook with marimo + static docs (#144)
* Replace tutorial notebook with marimo + static docs

Jupyter notebooks (.ipynb) are hostile to code review: every cell output
is a base64-embedded blob that churns on every run, and a 27 MB
examples.ipynb is essentially unreviewable. Moving the canonical
tutorial to a git-friendly marimo notebook and a static Markdown
walkthrough keeps code review diffs small, makes the source diffable
in pull requests, and lets the rendered tutorial live alongside the
library on the GitHub Pages site.

- Replace notebooks/examples.ipynb with notebooks/tutorial.py
  (marimo notebook, 35 cells, 15.1 KB).
- Add docs/tutorial.md with the same walkthrough rendered as Markdown
  plus 10 inline PNGs at docs/img/tour-01..tour-10-*.png extracted
  from the original notebook's cell outputs.
- Add Tutorial entry to mkdocs.yml nav; link from docs/index.md and
  README.md. README's inline tutorial block is replaced with a pointer
  table to docs/tutorial.md (README: 1062 -> 112 lines).
- Add marimo>=0.23.0 to requirements.txt; update .gitignore to keep
  the new tutorial.py whitelisted and to ignore marimo caches
  (__marimo__/, *.marimo).
- Fix mkdocs.yml site_url placeholder
  (yourusername.github.io -> marceloprates.github.io) so the GitHub
  Pages site's canonical links and sitemap point at the real domain.
- The 23 unrelated demo notebooks that lived alongside the tutorial
  are kept untracked in notebooks/untracked/ (gitignored as before).

* Restore README tutorial pointer and update Colab link

Follow-up to the tutorial-marimo conversion. The previous rebase onto
the upstream CI commit (ba59f1f) accidentally dropped the new README.md
rewrite because 'git checkout --ours' during a rebase selects the
upstream side, not the commit being applied. This restores the
112-line README.md with the tutorial pointer and updates the Colab
link from notebooks/examples.ipynb to notebooks/tutorial.py.

* Remove obsolete generate-readme CI workflow

The generate-readme.yml workflow and the notebooks_to_readme.sh script
it depended on were designed to run notebooks/examples.ipynb and
regenerate README.md from its cell outputs. Since examples.ipynb is
gone (replaced by the marimo notebook and static docs/tutorial.md),
this pipeline has no purpose and was failing the PR check.

Also removes the 13 orphan temp_readme_*.png files that the CI had
committed to pictures/README/ in ba59f1f — their source notebook
no longer exists.
2026-07-30 12:24:36 -03:00

113 lines
5.4 KiB
Markdown

# prettymaps
A minimal Python library to draw customized maps from [OpenStreetMap](https://www.openstreetmap.org/#map=12/11.0733/106.3078) created using the [osmnx](https://github.com/gboeing/osmnx), [matplotlib](https://matplotlib.org/), [shapely](https://shapely.readthedocs.io/en/stable/index.html) and [vsketch](https://github.com/abey79/vsketch) packages.
![](https://github.com/marceloprates/prettymaps/raw/main/pictures/heerhugowaard.png)
# [![Docs](https://img.shields.io/badge/docs-GitHub%20Pages-blue?logo=github)](https://marceloprates.github.io/prettymaps/) [![PyPI](https://img.shields.io/pypi/v/prettymaps)](https://pypi.org/project/prettymaps/) [![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/) [![License](https://img.shields.io/badge/license-AGPL%20v3.0-green)](LICENSE)
This work is [licensed](LICENSE) under a GNU Affero General Public License v3.0 (you can make commercial use, distribute and modify this project, but must **disclose** the source code with the license and copyright notice)
## Note about crediting and NFTs:
- Please keep the printed message on the figures crediting my repository and OpenStreetMap ([mandatory by their license](https://www.openstreetmap.org/copyright)).
- I am personally **against** NFTs for their [environmental impact](https://earth.org/nfts-environmental-impact/), the fact that they're a [giant money-laundering pyramid scheme](https://twitter.com/smdiehl/status/1445795667826208770) and the structural incentives they create for [theft](https://twitter.com/NFTtheft) in the open source and generative art communities.
- **I do not authorize in any way this project to be used for selling NFTs**, although I cannot legally enforce it. **Respect the creator**.
- The [AeternaCivitas](https://magiceden.io/marketplace/aeterna_civitas) and [geoartnft](https://www.geo-nft.com/) projects have used this work to sell NFTs and refused to credit it. See how they reacted after being exposed: [AeternaCivitas](https://github.com/marceloprates/prettymaps/raw/main/pictures/NFT_theft_AeternaCivitas.jpg), [geoartnft](https://github.com/marceloprates/prettymaps/raw/main/pictures/NFT_theft_geoart.jpg).
- **I have closed my other generative art projects on Github and won't be sharing new ones as open source to protect me from the NFT community**.
<a href='https://ko-fi.com/marceloprates_' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi1.png?v=3' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
## As seen on [Hacker News](https://web.archive.org/web/20210825160918/https://news.ycombinator.com/news):
![](https://github.com/marceloprates/prettymaps/raw/main/pictures/hackernews-prettymaps.png)
## [prettymaps subreddit](https://www.reddit.com/r/prettymaps_/)
## [Tutorial](notebooks/tutorial.py) (marimo) · [Google Colaboratory Demo](https://colab.research.google.com/github/marceloprates/prettymaps/blob/master/notebooks/tutorial.py)
# Installation
### Install locally:
Install prettymaps with:
```
pip install prettymaps
```
### Install on Google Colaboratory:
Install prettymaps with:
```
!pip install -e "git+https://github.com/marceloprates/prettymaps#egg=prettymaps"
```
Then **restart the runtime** (Runtime -> Restart Runtime) before importing prettymaps
# Run front-end
After prettymaps is installed, you can run the front-end (streamlit) application from the prettymaps repository using:
```
streamlit run app.py
```
# Tutorial
The full tutorial is at **[docs/tutorial.md](docs/tutorial.md)** — a markdown walkthrough with rendered images, the `[Plot]` dataclass fields, the `layers`/`style` parameters, presets, multiplot, hillshade, and keypoints.
![Heerhugowaard sample](docs/img/tour-01-heerhugowaard.png)
**Quick start:**
```python
import prettymaps
plot = prettymaps.plot('Stad van de Zon, Heerhugowaard, Netherlands')
```
| Resource | Where to find it |
|---|---|
| Full tutorial (markdown + images) | [`docs/tutorial.md`](docs/tutorial.md) |
| Interactive marimo notebook (runnable) | [`notebooks/tutorial.py`](notebooks/tutorial.py) |
| Open in Google Colab | [Open in Colab](https://colab.research.google.com/github/marceloprates/prettymaps/blob/master/notebooks/tutorial.py) |
| Streamlit front-end | `streamlit run app.py` |
### Run the tutorial locally (marimo)
```sh
# Install marimo (already in requirements.txt)
pip install marimo
# Open the notebook in your browser
marimo edit notebooks/tutorial.py
```
### Customizing parameters
The most important `prettymaps.plot()` parameters are:
- **`layers`** — dict of OpenStreetMap layers to fetch.
- **`style`** — dict of matplotlib style parameters per layer.
- **`preset`** — load a JSON preset (e.g. `'default'`, `'minimal'`, `'macao'`, `'tijuca'`).
- **`circle`** / **`radius`** / **`dilate`** — boundary shape.
`plot` is a dataclass with `geodataframes` (per-layer GeoDataFrames), `fig`, and `ax`.
```python
plot = prettymaps.plot(
'Praça Ferreira do Amaral, Macau',
circle=True,
radius=1100,
layers={
"water": {"tags": {"natural": ["water", "bay"]}},
"building": {"tags": {"building": True}},
},
style={
"water": {"fc": "#a1e3ff", "ec": "#2F3737"},
"building": {"palette": ["#FFC857", "#E9724C", "#C5283D"]},
},
)
```
![Macau, custom parameters](docs/img/tour-03-macau-custom.png)
See [`docs/tutorial.md`](docs/tutorial.md) for the full set of examples (Macau, Bom Fim, mosaic, Barcelona plotter, Tijuca, multiplot, hillshade, Garopaba keypoints).