How to Combine Multiple Maps Using python `multiplot` Function in prettymaps

Use prettymaps.multiplot() to render several geographic regions on a single Matplotlib canvas by passing Subplot objects that each encapsulate a query and its own styling parameters.

The prettymaps open-source library (marceloprates/prettymaps) generates artistic maps from OpenStreetMap data. While plot() produces single-map visualizations, the multiplot() function enables composite layouts—ideal for city comparisons, regional surveys, or thematic collections. This guide explains the internal mechanics and practical implementation based on the actual source code.

Understanding the Multiplot Architecture

The Three Public Entry Points

In prettymaps/__init__.py, the library exposes three key functions:

  • plot() – Renders a single map to a given axis
  • multiplot() – Orchestrates multiple maps on a shared figure
  • Subplot – A lightweight data container for per-map configuration

The multiplot() implementation resides in prettymaps/draw.py (lines 1270–1320), where it coordinates figure creation, subplot iteration, and final rendering.

How multiplot() Processes Multiple Maps

The function executes a four-stage pipeline, as implemented in the source:

  1. Figure initialization – Creates a Matplotlib figure via plt.figure() and a single master axis with plt.subplot(111)

  2. Backend selection – Checks for plotter=True in kwargs to toggle between standard Matplotlib rendering and the experimental Plotter API

  3. Subplot loop – Iterates over each Subplot instance, calling the internal plot() function with merged parameters:

plot(
    subplot.query,
    ax=ax,
    multiplot=True,
    **override_params(...),
    show=False,
)

This loop appears at draw.py lines 1280–1305. The multiplot=True flag suppresses duplicate attribution handling, while override_params() resolves conflicts between global and per-subplot settings.

  1. Finalization – Hides axis borders with ax.axis("off") and optionally displays the figure

Creating Subplot Containers

The Subplot Data Class

Defined at draw.py lines 70–84, Subplot is a minimal container storing:

Attribute Purpose
query Geographic region string or OSM tag query
kwargs Dictionary of overrides for that specific map

Instantiation requires no dependencies beyond the class itself:

from prettymaps import Subplot, multiplot

s1 = Subplot(query="New York, USA", kwargs={"load_preset": "default"})
s2 = Subplot(query="Paris, France", kwargs={"load_preset": "minimal"})

multiplot(s1, s2, figsize=(12, 8))

Parameter Override Logic

The override_params() function (invoked within multiplot) implements careful precedence:

  • Per-subplot kwargs take priority over global multiplot() arguments
  • The load_preset flag receives special protection to prevent accidental override
  • Style dictionaries, layer configurations, and drawing parameters all merge cleanly

This design allows each map to maintain distinct visual characteristics while sharing the same figure context.

Practical Code Examples

Two-City Comparison

Create a minimalist side-by-side of major cities:

from prettymaps import Subplot, multiplot

ny = Subplot("New York, USA", kwargs={"load_preset": "default"})
tokyo = Subplot("Tokyo, Japan", kwargs={"load_preset": "minimal"})

multiplot(ny, tokyo, figsize=(12, 6))

Custom Styles Per Subplot

Apply individual color schemes and layer configurations:

from prettymaps import Subplot, multiplot

s1 = Subplot(
    query="Berlin, Germany",
    kwargs={
        "load_preset": "default",
        "style": {"land": "#e0e0e0", "background": "#ffffff"},
        "layers": {"buildings": {"fill": "#ffcc00", "alpha": 0.8}},
    },
)

s2 = Subplot(
    query="Copenhagen, Denmark",
    kwargs={
        "load_preset": "minimal",
        "style": {"land": "#f5f5f5"},
        "layers": {"water": {"fill": "#4a90d9", "alpha": 0.6}},
    },
)

multiplot(s1, s2, figsize=(14, 7), credit={"text": "European capitals comparison"})

Three-Map Layout with Varied Complexity

Mix detailed and minimal renderings:

from prettymaps import Subplot, multiplot

s1 = Subplot(
    "Sydney, Australia",
    kwargs={
        "load_preset": "default",
        "style": {"land": "#e8f5e9"},
        "layers": {
            "water": {"fill": "#b3e5fc"},
            "buildings": {"fill": "#a1887f"}
        },
    },
)

s2 = Subplot(
    "Rio de Janeiro, Brazil",
    kwargs={
        "load_preset": "default",
        "style": {"land": "#fff3e0"},
        "layers": {"vegetation": {"fill": "#c8e6c9"}},
    },
)

s3 = Subplot(
    "Reykjavik, Iceland",
    kwargs={"load_preset": "minimal", "style": {"land": "#eceff1"}},
)

multiplot(s1, s2, s3, figsize=(15, 5), credit={"text": "Global coastal cities"})

Using the Plotter Backend

Enable interactive rendering for web-based workflows:

from prettymaps import Subplot, multiplot

s1 = Subplot("Amsterdam, Netherlands", kwargs={"load_preset": "default"})
s2 = Subplot("Venice, Italy", kwargs={"load_preset": "default"})

multiplot(s1, s2, figsize=(10, 5), plotter=True)

Key Source Files and Their Roles

File Function Relevant Lines
prettymaps/draw.py Core implementation of multiplot(), Subplot class, and parameter merging 70–84 (Subplot), 1280–1305 (multiplot loop)
prettymaps/__init__.py Public API exports Full module
prettymaps/presets/*.json Styling presets referenced via load_preset Preset directory
tests/test.py Validation suite including multiplot smoke tests Test implementations

Configuration Options Reference

Global multiplot() Parameters

Parameter Type Effect
figsize tuple (width, height) Dimensions in inches for the Matplotlib figure
credit dict or None Attribution text configuration; applied once to entire canvas
plotter bool Switches to experimental Plotter API when True

Per-Subplot Valid kwargs

Any argument accepted by plot() can be passed through Subplot.kwargs:

  • load_preset – Name of JSON preset file
  • style – Dictionary of color overrides
  • layers – Layer-specific rendering rules
  • dpi – Resolution for raster output
  • buffer – Geographic expansion around query region

Why the Design Works

Stateless core rendering – The plot() function accepts an external ax parameter and does not maintain global state, enabling safe repeated invocation.

Controlled attribution – The multiplot=True internal flag prevents duplicate copyright notices that would otherwise appear on every sub-render.

Flexible parameter inheritance – The override_params() merge strategy preserves intentional per-subplot customization without exposing complexity to users.

Summary

  • Import Subplot and multiplot from prettymaps to compose multiple maps
  • Each Subplot requires a geographic query and accepts custom kwargs for styling
  • multiplot() creates a shared Matplotlib figure, iterates through subplots, and applies parameter overrides automatically
  • Use load_preset, style, and layers keys to differentiate individual maps
  • Pass plotter=True for interactive Plotter-backend rendering
  • Control global layout with figsize and unified attribution via credit

Frequently Asked Questions

What's the difference between plot() and multiplot()?

plot() renders a single map to a specified axis and handles its own figure management. multiplot() creates a figure, accepts multiple Subplot objects, and orchestrates their rendering with proper attribution handling and parameter merging. Use plot() for standalone maps; use multiplot() for composites.

Can I mix different presets in one multiplot?

Yes. Each Subplot carries its own kwargs dictionary, including independent load_preset values. The override_params() function in draw.py protects preset loading during parameter merging, ensuring your per-subplot choices persist.

How do I control the layout arrangement of multiple maps?

multiplot() currently uses a single axis (plt.subplot(111)) and overlays maps at different positions. For custom grid arrangements, call plot() directly with manually created axes using plt.subplots() or GridSpec, then omit multiplot() entirely. The multiplot() function prioritizes convenience over granular layout control.

Why might attribution text appear duplicated, and how do I prevent it?

The multiplot=True internal flag suppresses per-subplot credit rendering. This flag is set automatically when multiplot() calls plot(). If using plot() directly for manual composition, pass credit=None to all but the final subplot to avoid duplication.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →