mapcetera

Real data.
Real photons.
On your wall.

Every poster starts as an open scientific dataset — NASA satellites, ESA land surveys, OpenStreetMap. Not a rendering. Not an illustration. Measured, processed, printed.

See the shop on Etsy →
Amsterdam 2024 — twelve-panel nighttime radiance poster. Each panel is one month of satellite data.

These posters start as real measurements: photons counted by a VIIRS sensor orbiting 824 km above the Earth, pixels classified by ESA's 10-metre land cover survey, coordinates queried live from OpenStreetMap. The pipeline that turns that data into a poster is versioned, reproducible, and city-agnostic. Every caption names the instrument, the archive, and the projection. Anyone can check.

How a poster is made

Stage 01

Find the data

The hardest decision in the project happened before a single line of code was written: what counts as real? Procedural generation, styled basemaps, data-driven illustrations — all of these exist, and none of them were what we wanted. The requirement we settled on was simple to state and hard to execute. Every data source has to be measured by a real instrument, published openly, and cite-able on the poster itself.

NASA Black Marble exists because a satellite called Suomi NPP has been circling Earth at 824 km every 101 minutes since 2011, and one of its instruments — the VIIRS Day/Night Band — is sensitive enough to detect a single lit street. That data is public domain. Anyone can download it. The commitment to use it, and only it, for the light was the whole design brief. Land cover comes from ESA WorldCover at 10 metre resolution. Ice cream shops come from OpenStreetMap. The city boundary comes from GADM. Nothing is invented.

Nighttime light
source     NASA Black Marble
product    VNP46A3 monthly composite
instrument VIIRS Day/Night Band
satellite  Suomi NPP / 824 km
licence    CC0 · no implied endorsement
Land cover
source     ESA WorldCover 2021 v2
resolution 10 m global
classes    10 = tree cover · 80 = water
licence    CC BY 4.0
Points of interest
source     OpenStreetMap contributors
access     Overpass API
licence    ODbL

Stage 02

Fetch, and fetch again

The first time a completed poster run reveals a black rectangle where January should be, you have a decision to make. Interpolate the gap. Copy from the adjacent month. Run a smooth that quietly erases the hole. Every one of those choices would make the poster look more complete. We didn't do any of them.

The gap stays black. The poster caption carries a source disclosure that was added on the second poster made, not the first. The first one, we quietly used three nights from the previous year without saying so. That felt wrong. It hasn't happened again. The pipeline now builds a fallback ladder automatically — if a night is missing from 2024, step back to 2023, then 2022 — and the count goes on every poster.

A black tile is a night the satellite couldn't see through the clouds. It stays black.

Poster caption — source disclosure

Source mix: 342 nights from 2024 · 22 nights from 2023 · 1 night from 2022
Gaps indicate cloud cover or missing satellite data.
Fallback years are used when a given night is unavailable.

Every poster carries this line. It wasn't in the first one.
The aggressive caching means a run can be interrupted and resumed at any point without re-downloading anything. A pipeline that took six hours the first time takes two minutes the second.

Stage 03

Project and grid

A poster of Oslo in the default web mapping projection would make the city look about 40% wider than it actually is. Nobody who lives there would recognise it. The fix is cartographic: every poster is reprojected into a local UTM zone centred on the city, where shapes are correct at that location.

For a single city this is a one-time lookup. For 197 world capitals running unattended overnight, it had to be automatic. The formula turns out to fit in two lines. Oslo and Berlin are in adjacent UTM zones. Nairobi is in the southern hemisphere and gets a different offset. None of this appears anywhere on the finished poster. It's why the poster looks right.

# UTM zone from city centroid — no manual lookup
zone <- floor((lon + 180) / 6) + 1
epsg <- if (lat >= 0) 32600 + zone else 32700 + zone
Berlin   → EPSG:32633   Oslo     → EPSG:32632
Nairobi → EPSG:32737   Bogotá   → EPSG:32618
Tokyo    → EPSG:32654   Sydney   → EPSG:32756

Stage 04

Design

The first version of the nighttime poster was on a white background, and it looked like a printout. Not a poster — a printout. The data rendered correctly, the colours mapped to the radiance values, but on white ground, light from a city at night becomes a grey blob with some orange highlights. It doesn't read as light.

The breakthrough was inverting it: start from black, and let the city emerge from the dark the way it actually looks from space. After that, every design decision became clearer. The colour ramp went through about a dozen iterations — early versions tried blue-to-white, then orange-to-white. What the data wanted was something colder in the midrange (where most city pixels live most of the time) and hotter only at the extremes: commercial cores, stadiums, event nights. Teal for the routine glow. Orange for when the city is really on. The ramp has been unchanged since the third poster.

Typography was slower. Bebas Neue for the city name because it reads as a label — assertive and geometric, not decorative. IBM Plex Mono for the caption because it should look like a specimen label from a scientific collection: instrument, satellite, archive, projection, in small grey monospace at the bottom of the frame.

#000000 #0A1E18 #173B45 #2A8078 #58C0A8 #FF8225
Berlin 2024 — twelve-panel monthly grid

When the data isn't a map

Sound posters

The same creative problem in a different domain: what does spoken language look like? The starting point was the Unknown Pleasures cover — Joy Division's 1979 album artwork, which is a stack of radio pulses from a pulsar, each emission offset upward into a ridge plot. That's the canonical data poster for sound, and it assumes regularity: the same width, the same time axis, stacked.

A spoken word doesn't have that shape. It starts in near-silence, builds as the consonant forms, widens through the vowel, then falls away. The bloom form came from asking what would happen if the ridgelines could grow with the sound — a narrow stem at the start that fans out as energy develops, like a plant opening. Hola, Hallo, Hello: the same concept in three languages. Spanish Hola is tight and staccato. German Hallo opens slowly, holds longer. English Hello stretches the vowel wide. Three different acoustic shapes from three versions of the same word.

The sounds for the final poster will be real voice recordings. The design question — what shape does spoken language want to be — was the interesting one.

Hola / Hallo / Hello — mel spectrograms rendered as bloom ridge plots

Stage 05

Prepare for print

The gap between a calibrated monitor and a piece of paper is wider than you expect. The first A0 test print came back on enhanced matte art paper and looked wrong. The blacks were dark grey. The teal gradient in the mid-brightness range — the range where most of the poster lives — was muddy and slightly brownish. The fine point lights of street clusters, which on screen read as crisp bright points on black, were slightly haloed from ink spreading into the paper fibres.

We tried lustre photo paper next (240 gsm, satin finish). The blacks came back. The contrast sharpened. But the satin coating had a mild sheen that competed with the subtle colour in the dark teal range and shifted how the gradient read under certain lights. The paper that finally worked was Global-Fap matte from Prodigi. It sounds like a compromise. It isn't: the specific coating on this paper holds black ink differently from standard matte, and the finished print looks almost exactly like the file. The blacks are deep. The teal is cold. The orange is warm. The output is a vector PDF at 300 DPI — a 60 × 80 cm poster is roughly 7,000 × 9,400 pixels — and Prodigi gets it print-ready from the R output directly.

Berlin 2024 nighttime radiance poster

Stage 06

Scale it

When Berlin worked, it took about two minutes. When Oslo ran next, it also took about two minutes — and nothing city-specific was hardcoded. That was the moment the product changed: it wasn't a poster, it was a machine that makes posters.

Change the city name in a config file and the pipeline computes the UTM zone, downloads the boundary, fetches the satellite data, and renders. A batch runner reads a spreadsheet of 197 world capitals, writes a config for each, and runs them unattended overnight. 197 cities. Roughly six hours. Nothing that required human attention until it was done. The run is fully resumable — each output is skipped if it already exists, so interrupting and restarting costs nothing. The product isn't Berlin or Oslo. The product is: ask for a city, get a poster. Any city. Overnight.

# config.yml — swap one line to go from Berlin to Bogotá
area:
  name:           Berlin       # ← change this
  country:        Germany
  crs_projected: EPSG:32633  # ← auto-computed
  bbox_buffer:    0.12
output:
  width_in:       33.1         # A0
  height_in:      46.8
  dpi:            300

What's in the shop

Oslo 2024 nighttime radiance — twelve monthly panels

Nighttime Radiance

A city's glow, measured from orbit, across every month of the year. Twelve panels. Real cloud gaps. No smoothing.

Berlin land cover — water and tree canopy density grid

Land Cover — Water & Trees

The same city, but its ecology: blue for water, green for canopy, gridded by density. ESA WorldCover at 10 m resolution.

Berlin ice cream map — 247 locations as coloured dots

Ice Cream Map

Every ice cream shop in a city, plotted as coloured dots. 247 locations. 2.77 per km². Change two lines in the config and it maps bakeries, cafés, or anything else OpenStreetMap knows about.

Sound poster — Hola / Hallo / Hello mel spectrograms as bloom ridge plots

Sound Posters

Audio as ridge plots — mel spectrograms rendered as stacked waves that grow wider as sound develops. Each word has a different shape.

What's in the data

Datasets
  NASA Black Marble    VNP46A2 (daily) · VNP46A3 (monthly composite)
                        CC0 / public domain · commercial use with attribution
                        No implied NASA endorsement
  ESA WorldCover       2021 v2 · 10 m resolution · CC BY 4.0
                        Tree cover = class 10 · Permanent water = class 80
  OpenStreetMap        © OpenStreetMap contributors · ODbL · Overpass API
  Boundaries           GADM / Nominatim · cached as GeoPackage

Instrument & orbit
  Sensor               VIIRS Day/Night Band
  Satellite            Suomi NPP · 824 km orbital altitude · polar orbit
  Archive              NASA LAADS DAAC · bearer token · public domain

Projection
  Source CRS           EPSG:4326 (geographic, WGS84)
  Output CRS           Local UTM zone · computed from city centroid
  Examples             Berlin EPSG:32633 · Oslo EPSG:32632 · Nairobi EPSG:32737

Print specs
  Format               A0 · 33.1 × 46.8 in · 84.1 × 118.9 cm
  Resolution           300 DPI · vector PDF (cairo_pdf) · ~7,000 × 9,400 px
  Gelato spec          PDF/X-4 · GRACoL 2006 output intent · 4 mm bleed
  Prodigi spec         RGB PDF · 300 DPI · print-ready from R output
  Paper                Global-Fap matte · Prodigi · powerful black, almost like dark silk

Fulfilment
  Network              Prodigi print-on-demand · UK, EU, US facilities
  Inks                 Water-based, low-toxicity
  Paper sourcing       Sustainably sourced
  Production model     Printed to order · no overproduction · no unsold stock

What's next

The pipeline generalises. If there's an open dataset and a visual question worth asking, it can probably become a poster. These are in progress.

Satellite Orbits

~14,900 live TLE records from CelesTrak. The geostationary ring at 36,000 km shows up as a golden band. The low-Earth population is a dense shell; above it, near silence.

Wind Fields

Streamlines from ERA5 reanalysis. The jet stream, trade winds, and seasonal reversals — all in one frame, at planetary scale.

Flight Trajectories

Flight paths from OpenSky Network. Every route over a city, bundled and rendered as a density field. The absence of flights tells its own story.

Genome Sequences

DNA sequences plotted on Hilbert curves. The fractal path preserves locality — neighbouring bases stay close on the page. Repetitive regions cluster visually.

See the shop

Real data. Real paper. Printed to order.


Visit mapcetera on Etsy →

Don't see your city? Every world capital is already in the pipeline. Ask, and it runs overnight.