Generating Output for Pen Plotters Using vsketch Plotter Mode in prettymaps
Set mode="plotter" in prettymaps.plot() to generate SVG output optimized for pen plotters via the integrated vsketch engine.
The prettymaps library extends beyond Matplotlib raster rendering to produce clean, scalable vector graphics suitable for physical pen plotters. By activating the vsketch plotter mode, the library translates OpenStreetMap geometries directly into SVG path commands that AxiDraw, Makelangelo, and other plotter hardware can execute without conversion.
How the vsketch Plotter Mode Works
The plotter pipeline lives entirely within prettymaps/draw.py and replaces the standard Matplotlib backend with a vsketch.Vsketch instance. The workflow proceeds through four coordinated stages:
- Mode detection —
init_plot()instantiatesvsketch.Vsketch()instead of Matplotlib Figure/Axes - Layer iteration —
draw_layers()passes geometries toplot_gdf()with vsketch context - Geometry dispatch —
plot_gdf()issuesvsk.geometry()commands for each shapely object - SVG output —
vsk.display()flushes the drawing queue to file
Core Implementation in prettymaps/draw.py
The mode branch occurs at lines 1010‑1014 in init_plot():
def init_plot(
title: str = "",
mode: str = "matplotlib",
...
):
if mode == "plotter":
vsk = vsketch.Vsketch()
vsk.size("a4", landscape=True)
return vsk, None
else:
# Standard Matplotlib path
fig, ax = plt.subplots(figsize=figsize)
return fig, ax
When mode="plotter", the function returns a Vsketch object and None for the axes handle, signaling downstream functions to use vsketch commands exclusively.
Drawing Geometries with vsketch Commands
The plot_gdf() function (lines 402‑424) handles the translation from GeoDataFrames to vsketch primitives. For each geometry in the layer:
if mode == "plotter":
vsk.stroke(kwargs.get("stroke", 1))
vsk.penWidth(kwargs.get("penWidth", 0.3))
vsk.fill(kwargs.get("fill", False))
vsk.geometry(shape)
Key vsketch parameters:
stroke— Controls stroke color (mapped from matplotlibecor explicit value)penWidth— Physical pen width in millimeters (default 0.3mm)fill— Boolean toggle for polygon fills; useFalsefor outline-only plotter artgeometry()— Accepts any shapelyPolygon,LineString,MultiPolygon, orGeometryCollection
After all layers process through draw_layers() (lines 995‑1005), the main plot() function executes vsk.display() at lines 1268‑1270 to finalize the SVG.
Practical Examples for Pen Plotter Output
Basic Plotter Mode Call
Generate a single-location SVG for water features:
import prettymaps
prettymaps.plot(
"Porto, Portugal",
mode="plotter",
layers={"water": {"tags": {"natural": "water"}}},
style={"water": {"fc": "#a1e3ff", "ec": "#2F3737"}},
save_as="porto.svg",
show=False,
)
The save_as parameter ensures the SVG writes to disk; show=False suppresses the Matplotlib preview window.
Multiplot Layout for Plotters
Create composited maps on a single plotter canvas:
import prettymaps
sub1 = prettymaps.Subplot("São Paulo, Brazil")
sub2 = prettymaps.Subplot("Rio de Janeiro, Brazil")
prettymaps.multiplot(
sub1, sub2,
mode="plotter",
figsize=(21, 14), # A3 dimensions in centimeters
save_as="brazil.svg",
show=False,
)
According to the prettymaps source code, multiplot() reuses the same Vsketch instance across subplots, positioning each map via vsketch's native coordinate transformation.
Fine-Tuned Pen Plotter Styling
Control physical pen characteristics for detailed architectural drawings:
prettymaps.plot(
"Amsterdam, Netherlands",
mode="plotter",
layers={"building": {"tags": {"building": True}}},
style={
"building": {
"palette": ["#FFC857", "#E9724C", "#C5283D"],
"stroke": 0.5, # Stroke color index or value
"penWidth": 0.1, # 0.1mm pen for fine lines
"fill": True, # Hatched fills via vsketch
}
},
save_as="amsterdam.svg",
show=False,
)
The penWidth parameter directly sets vsketch.penWidth(), enabling precise control over line weight without post-processing.
Preset and Style Integration
Plotter mode respects the same preset system as Matplotlib mode. The manage_presets() and override_params() functions (lines 1089‑1125) normalize style dictionaries before they reach plot_gdf(). This means:
- Preset
.jsonfiles work unchanged between modes - Color values (
fc,ec) convert to vsketch-compatible stroke/fill specifications - Layer-specific overrides pass through transparently
Source File Reference
| File | Purpose | Key Functions |
|---|---|---|
prettymaps/draw.py |
Drawing engine with vsketch integration | plot(), init_plot(), draw_layers(), plot_gdf() |
prettymaps/__init__.py |
Public API exposure | plot(), Subplot(), multiplot() |
prettymaps/fetch.py |
OSM data retrieval | get_osm_geometries() |
app.py |
Streamlit interface with plotter support | Wrapper calls to plot(mode="plotter") |
Summary
- Activate plotter mode by passing
mode="plotter"toprettymaps.plot()orprettymaps.multiplot() - The vsketch backend creates clean SVG output without external dependencies, as implemented in
prettymaps/draw.py - Pen characteristics are controlled via
penWidth,stroke, andfillparameters in layer style dictionaries - Multiplot layouts render multiple maps on a single plotter canvas using shared
Vsketchstate - Output SVGs are ready for direct use with AxiDraw, Makelangelo, and other standard pen plotters
Frequently Asked Questions
What pen plotter hardware works with prettymaps output?
Any device that accepts standard SVG files works directly. The vsketch-generated SVGs use simple path elements without proprietary extensions, making them compatible with Evil Mad Scientist's AxiDraw, Marginally Clever's Makelangelo, and most other consumer plotters. No additional conversion software is required.
How do I control hatch patterns for filled areas?
Set fill=True in your layer style and rely on vsketch's default hatching behavior, or export with fill=False and manually add hatching in Inkscape or your plotter control software. The current plot_gdf() implementation delegates fill rendering entirely to vsketch's internal algorithms.
Can I mix Matplotlib and plotter outputs in the same script?
Yes. Each call to prettymaps.plot() is independent; specify mode="matplotlib" for preview and mode="plotter" for final vector output. The show=False parameter prevents window conflicts when alternating modes in Jupyter notebooks or automated pipelines.
Why is my SVG output in A4 landscape format?
init_plot() hardcodes vsk.size("a4", landscape=True) at lines 1012‑1013. For custom dimensions, fork the repository or patch prettymaps/draw.py to accept a paper_size parameter before the Vsketch initialization.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →