SkillAgentSearch skills...

Prettymaps

Draw pretty maps from OpenStreetMap data! Built with osmnx +matplotlib + shapely

Install / Use

/learn @marceloprates/Prettymaps
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

prettymaps

A minimal Python library to draw customized maps from OpenStreetMap created using the osmnx, matplotlib, shapely and vsketch packages.

Docs PyPI Python License

This work is licensed 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).
  • I am personally against NFTs for their environmental impact, the fact that they're a giant money-laundering pyramid scheme and the structural incentives they create for theft 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 and geoartnft projects have used this work to sell NFTs and refused to credit it. See how they reacted after being exposed: AeternaCivitas, geoartnft.
  • 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:

prettymaps subreddit

Google Colaboratory Demo

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

Plotting with prettymaps is very simple. Run:

prettymaps.plot(your_query)

your_query can be:

  1. An address (Example: "Porto Alegre"),
  2. Latitude / Longitude coordinates (Example: (-30.0324999, -51.2303767))
  3. A custom boundary in GeoDataFrame format
%reload_ext autoreload
%autoreload 2

import prettymaps

plot = prettymaps.plot('Stad van de Zon, Heerhugowaard, Netherlands')
Fetching geodataframes took 14.43 seconds



png

You can also choose from different "presets" (parameter combinations saved in JSON files)

See below an example using the "minimal" preset

import prettymaps

plot = prettymaps.plot(
    'Stad van de Zon, Heerhugowaard, Netherlands',
    preset = 'minimal'
)
Fetching geodataframes took 5.48 seconds



png

Run

prettymaps.presets()

to list all available presets:

import prettymaps

prettymaps.presets()
<div> <style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style> <table border="1" class="dataframe"> <thead> <tr style="text-align: right;"> <th></th> <th>preset</th> <th>params</th> </tr> </thead> <tbody> <tr> <th>0</th> <td>abraca-redencao</td> <td>{'layers': {'perimeter': {}, 'streets': {'widt...</td> </tr> <tr> <th>1</th> <td>barcelona</td> <td>{'layers': {'perimeter': {'circle': False}, 's...</td> </tr> <tr> <th>2</th> <td>barcelona-plotter</td> <td>{'layers': {'streets': {'width': {'primary': 5...</td> </tr> <tr> <th>3</th> <td>cb-bf-f</td> <td>{'layers': {'streets': {'width': {'trunk': 6, ...</td> </tr> <tr> <th>4</th> <td>default</td> <td>{'layers': {'perimeter': {}, 'streets': {'widt...</td> </tr> <tr> <th>5</th> <td>heerhugowaard</td> <td>{'layers': {'perimeter': {}, 'streets': {'widt...</td> </tr> <tr> <th>6</th> <td>macao</td> <td>{'layers': {'perimeter': {}, 'streets': {'cust...</td> </tr> <tr> <th>7</th> <td>minimal</td> <td>{'layers': {'perimeter': {}, 'streets': {'widt...</td> </tr> <tr> <th>8</th> <td>plotter</td> <td>{'layers': {'perimeter': {}, 'streets': {'widt...</td> </tr> <tr> <th>9</th> <td>tijuca</td> <td>{'layers': {'perimeter': {}, 'streets': {'widt...</td> </tr> </tbody> </table> </div>

To examine a specific preset, run:

import prettymaps

prettymaps.preset('default')
Preset(params={'layers': {'perimeter': {}, 'streets': {'width': {'motorway': 5, 'trunk': 5, 'primary': 4.5, 'secondary': 4, 'tertiary': 3.5, 'cycleway': 3.5, 'residential': 3, 'service': 2, 'unclassified': 2, 'pedestrian': 2, 'footway': 1}}, 'waterway': {'tags': {'waterway': ['river', 'stream']}, 'width': {'river': 20, 'stream': 10}}, 'building': {'tags': {'building': True, 'landuse': 'construction'}}, 'water': {'tags': {'natural': ['water', 'bay']}}, 'sea': {}, 'forest': {'tags': {'landuse': 'forest'}}, 'green': {'tags': {'landuse': ['grass', 'orchard'], 'natural': ['island', 'wood', 'wetland'], 'leisure': ['dog_park', 'disc_golf_course', 'garden', 'golf_course', 'park', 'pitch', 'sports_centre', 'track']}}, 'rock': {'tags': {'natural': 'bare_rock'}}, 'beach': {'tags': {'natural': 'beach'}}, 'parking': {'tags': {'amenity': 'parking', 'highway': 'pedestrian', 'man_made': 'pier'}}}, 'style': {'perimeter': {'fill': False, 'lw': 0, 'zorder': 0}, 'background': {'fc': '#F2F4CB', 'zorder': -1}, 'green': {'fc': '#8BB174', 'ec': '#2F3737', 'hatch_c': '#A7C497', 'hatch': 'ooo...', 'lw': 1, 'zorder': 1}, 'forest': {'fc': '#64B96A', 'ec': '#2F3737', 'lw': 1, 'zorder': 2}, 'water': {'fc': '#a8e1e6', 'ec': '#2F3737', 'hatch_c': '#9bc3d4', 'hatch': 'ooo...', 'lw': 1, 'zorder': 99}, 'sea': {'fc': '#a8e1e6', 'ec': '#2F3737', 'hatch_c': '#9bc3d4', 'hatch': 'ooo...', 'lw': 1, 'zorder': 99}, 'waterway': {'fc': '#a8e1e6', 'ec': '#2F3737', 'hatch_c': '#9bc3d4', 'hatch': 'ooo...', 'lw': 1, 'zorder': 200}, 'beach': {'fc': '#FCE19C', 'ec': '#2F3737', 'hatch_c': '#d4d196', 'hatch': 'ooo...', 'lw': 1, 'zorder': 3}, 'parking': {'fc': '#F2F4CB', 'ec': '#2F3737', 'lw': 1, 'zorder': 3}, 'streets': {'fc': '#2F3737', 'ec': '#475657', 'alpha': 1, 'lw': 0, 'zorder': 4}, 'building': {'palette': ['#433633', '#FF5E5B'], 'ec': '#2F3737', 'lw': 0.5, 'zorder': 5}, 'rock': {'fc': '#BDC0BA', 'ec': '#2F3737', 'lw': 1, 'zorder': 6}}, 'circle': None, 'radius': 500})

Insted of using the default configuration you can customize several parameters. The most important are:

  • layers: A dictionary of OpenStreetMap layers to fetch.
    • Keys: layer names (arbitrary)
    • Values: dicts representing OpenStreetMap queries
  • style: Matplotlib style parameters
    • Keys: layer names (the same as before)
    • Values: dicts representing Matplotlib style parameters
plot = prettymaps.plot(
    # Your query. Example: "Porto Alegre" or (-30.0324999, -51.2303767) (GPS coords)
    your_query,
    # Dict of OpenStreetMap Layers to plot. Example:
    # {'building': {'tags': {'building': True}}, 'water': {'tags': {'natural': 'water'}}}
    # Check the /presets folder for more examples
    layers,
    # Dict of style parameters for matplotlib. Example:
    # {'building': {'palette': ['#f00','#0f0','#00f'], 'edge_color': '#333'}}
    style,
    # Preset to load. Options include:
    # ['default', 'minimal', 'macao', 'tijuca']
    preset,
    # Save current parameters to a preset file.
    # Example: "my-preset" will save to "presets/my-preset.json"
    save_preset,
    # Whether to update loaded preset with additional provided parameters. Boolean
    update_preset,
    # Plot with circular boundary. Boolean
    circle,
    # Plot area radius. Float
    radius,
    # Dilate the boundary by this amount. Float
    dilate
)

plot is a python dataclass containing:

@dataclass
class Plot:
    # A dictionary of GeoDataFrames (one for each plot layer)
    geodataframes: Dict[str, gp.GeoDataFrame]
    # A matplotlib figure
    fig: matplotlib.figure.Figure
    # A matplotlib axis object
    ax: matplotlib.axes.Axes

Here's an examp

Related Skills

View on GitHub
GitHub Stars12.2k
CategoryDevelopment
Updated4h ago
Forks590

Languages

Jupyter Notebook

Security Score

100/100

Audited on Mar 20, 2026

No findings