Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Making maps with AI

What an AI assistant gets wrong about maps, and how to check its work

Eindhoven University of Technology

The 2026/27 theme of the Coding Café is AI in research software development, and the #30DayMapChallenge is a good place to try it: a small, self-contained task, with a result you can see. AI assistants and coding agents are genuinely good at map code. They know the GeoPandas and sf APIs better than most of us, and they will happily write the forty lines of matplotlib styling you did not want to look up.

They are also confidently wrong in ways that are specific to maps, and a wrong map looks just as convincing as a right one. This page is about getting the first without the second.

What goes wrong

These are the failures we see again and again, roughly in order of how much damage they do.

FailureWhat it looks likeWhy it happens
Invented dataPlausible coordinates, counts or place names that do not exist. A “sample dataset” that the code quietly uses instead of the real one.When a download fails or no data is given, the model fills the gap rather than stopping.
Wrong or missing CRSDistances in degrees, a squashed map, buffers that are ellipses, layers that do not line upModels often skip the reprojection step, or reproject only one of two layers.
Lat/lon swappedPoints in the Indian Ocean off Somalia instead of EindhovenTraining data mixes (lat, lon) and (x, y) conventions.
Wrong OSM tagsamenity=coffee_shop (no such value), or missing ways and relations so half the features are goneThe model guesses tags instead of checking the wiki.
Stale APIsCode that calls functions renamed or removed several versions ago (geometries_from_place in old osmnx, unary_union warnings)Training data lags behind the libraries.
No attributionA map of OSM data with no “© OpenStreetMap contributors”Credits are not part of “make a map” unless you ask.
Misleading designRaw counts on a choropleth of areas of different sizes; a rainbow palette; a legend that does not match the classesThe model optimises for a map that looks finished.

None of these produce an error. The script runs, the PNG looks good, and the map is wrong.

Prompting so it does not happen

Give the assistant the same information you would give a new colleague. A prompt that works well for map code has five parts:

  1. The data, with its path, format and CRS: “data/eindhoven_cafes.geojson, points, EPSG:4326”. If it needs to download something, name the source.

  2. The CRS to work in: “Reproject everything to EPSG:28992 before plotting or measuring.”

  3. What the map should show, as a statement: “Show that cafés with a terrace cluster in the city centre.”

  4. What must be on the image: title, legend with units, credit line with “© OpenStreetMap contributors”, the CRS.

  5. What to do when stuck: “If the data is missing or a download fails, stop and tell me. Do not invent data, not even as a placeholder.”

An example:

Using Python with geopandas and matplotlib, make a map from data/eindhoven_cafes.geojson
(points, EPSG:4326) and data/eindhoven_boundary.geojson (polygon, EPSG:4326).
Reproject both to EPSG:28992 first.

Show the cafés that have outdoor_seating=yes in red and all others in grey, on the boundary
in light grey. Title: "Where to sit outside with a coffee in Eindhoven". Add a legend and a
credit line: "Data: © OpenStreetMap contributors (ODbL) | EPSG:28992".

Save to maps/day01-<me>/map.png at 7x7 inches, 200 dpi, white background.
Use only the data in these files. If something is missing, stop and ask me.

For a coding agent working in a repository, put the rules in an instruction file (AGENTS.md, CLAUDE.md or .github/copilot-instructions.md) so you do not have to repeat them in every prompt. The starter repo’s AGENTS.md is a ready-made example to copy.

Checking the result

Never accept a map because it looks right. These checks take a minute and catch every failure in the table above. The code below runs them on the Day 1 data; put the same lines at the end of any script an AI wrote for you.

91 features; ['Point']
89.4 km²
100.0 % of cafés inside the boundary

Then, by eye:

If the assistant made a mistake, tell it what was wrong rather than asking it to “fix the map”. “The points are in the Indian Ocean: you swapped latitude and longitude in points_from_xy” gets a correct answer; “it looks wrong” gets a different guess.

Being open about it

The challenge has one rule about AI: every map’s README says, in one line, what the AI did and what you did.

AI disclosure: AI wrote the plotting code, I chose the data and the projection.

AI disclosure: I wrote the code; an assistant helped me debug a CRS error.

AI disclosure: No AI used.

This is not a confession. It makes AI use something the group can learn from: which tasks it helped with, and which it made harder. Whatever the AI produced, you are responsible for checking that the data and the map are real and correct.

Day 10: Prompting only

Day 10 asks for a map made entirely through an AI chat or agent: you may not edit the code yourself. It is a good test of everything on this page. Save your prompts (for example in prompts.md next to the map), and note how many rounds it took and what you had to correct. The data still has to be real: “prompting only” means the AI writes the code, not the facts.

Day 27: New tool

A good day to try an AI coding agent if you have only used chat so far, or the other way round. Compare the result with a map you made yourself earlier in the month.