Which Map Elements Are Actually Required

Problem statement

Every cartography checklist lists the same furniture: title, legend, scale bar, north arrow, graticule, inset, data source, projection note, neatline, credits. Applied uniformly, that list produces maps where the apparatus outweighs the data.

Some of those elements are load-bearing, some are conditional, and at least two are usually wrong to include. A north arrow on a north-up map of a familiar country tells the reader nothing they did not assume. A scale bar on a small-scale Web Mercator map of Europe is not merely redundant โ€” it is false: at latitude 52ยฐ the Web Mercator grid stretches distance by a factor of 1.62, and at 60ยฐ by 2.00, so one bar cannot be right across the map.

The space is not free either. A 7 pt label occupies about 78 ร— 10 pixels in a plotting area of 620 ร— 462 โ€” every element added is space the subject does not get.

Quick answer

Three tests for each element: does it answer a question the reader will have, is it correct at this projection and scale, and does the map lose something if it goes?

def needs_element(element, *, map_scale, projection, north_up=True,
                  audience_knows_area=True, has_categories=False):
    if element == "scale bar":
        return not is_conformal_at_scale(projection, map_scale)   # see below
    if element == "north arrow":
        return not north_up                                       # rotation only
    if element == "legend":
        return has_categories or True         # a choropleth always needs one
    if element == "locator inset":
        return not audience_knows_area
    if element == "graticule":
        return map_scale < 1 / 5_000_000      # small-scale only
    if element in ("data source", "date", "projection"):
        return True                           # always; they are provenance
    raise ValueError(element)
Grid of six map elements against when each is needed and why.
Only the top two rows survive on every map.

Step-by-step solution

1. Always: the source, the date and the projection

These three are provenance, not decoration, and they are the elements most often omitted. They cost one line of 6 pt text in the corner and they answer the questions that arrive by email a month later:

Source: ONS mid-2025 estimates ยท Boundaries: OS BoundaryLine 2026-04
Projection: British National Grid (EPSG:27700) ยท Made 2026-09-05

The projection matters because it decides whether distances and areas on the map can be compared at all.

2. Almost always: a legend, if anything is encoded by colour or size

If the map encodes a variable, the reader needs the key. The exceptions are genuinely self-explanatory maps โ€” a single-colour location map, a map whose categories are directly labelled โ€” and in those cases the legend is redundant rather than wrong.

Legend design is where most of the value is: interval labels rather than class numbers, units on the title, and "no data" shown explicitly rather than left as a mystery grey.

3. Conditional: a scale bar, and only where scale is constant

A scale bar asserts that one printed distance equals one ground distance across the whole map. That is true for a large-scale map in a projected CRS and false for a small-scale map in almost any projection.

Measured in Web Mercator, the ratio of grid distance to true ground distance along a parallel:

latitude   grid metres   true metres   ratio
    0ยฐ        111,319       111,319    1.00
   30ยฐ        111,319        96,486    1.15
   45ยฐ        111,319        78,846    1.41
   52ยฐ        111,319        68,677    1.62
   60ยฐ        111,319        55,799    2.00
   70ยฐ        111,319        38,186    2.92

A single bar drawn on a Web Mercator map of Europe is wrong by more than 50% between its top and bottom. Either reproject to something appropriate for the extent, or omit the bar and give the scale in words with the latitude it applies to.

4. Rarely: a north arrow

A north arrow answers "which way is up?" It earns its place when the map is rotated, when the projection curves the meridians visibly, or when the audience genuinely cannot assume north-up โ€” a site plan aligned to a building, a subsurface section, a polar map.

On a north-up map of a country the reader recognises, it is furniture. Removing it is not a violation of anything; it is one fewer thing competing with the data.

5. Conditional: a locator inset

An inset answers "where in the world is this?" It is essential when the audience does not know the area and useless when they do. The test is the audience, not the map.

When you do include one, keep it tiny, keep it quiet, and give it a visible extent rectangle. An inset that needs its own legend has become a second map.

6. Rarely: a graticule

Coordinate lines are useful on small-scale maps, on navigation charts and where the reader will read coordinates off the page. On a district-level thematic map they add a grid of lines that competes with the data for no benefit.

If included, they belong to tier 3 of the hierarchy: measured contrast around 2.56:1 against white โ€” visible when looked for, invisible otherwise.

7. Never: elements that lie

Two specific cases worth naming, because both are common:

  • A scale bar on a map whose scale varies โ€” the Web Mercator case above.
  • A north arrow on a projection where north is not a constant direction across the map, such as a wide conic or azimuthal projection where meridians converge visibly.

An element that is wrong is worse than a missing one, because the reader trusts it.

Bar chart of Web Mercator scale inflation from 1.00 at the equator to 2.92 at 70 degrees.
Shape is preserved, which is what makes the distance error so easy to ship.

Code examples

Example 1 โ€” deciding, in code, from the projection and extent

from pyproj import CRS, Geod, Transformer


def scale_bar_is_honest(crs, bounds, tolerance=0.02):
    """Would one scale bar be correct across this map, to within `tolerance`?

    Compares grid distance with true geodesic distance along the top and the
    bottom of the extent. A ratio spread beyond the tolerance means a single
    bar cannot be right everywhere.
    """
    crs = CRS.from_user_input(crs)
    to_wgs = Transformer.from_crs(crs, 4326, always_xy=True)
    geod = Geod(ellps="WGS84")
    minx, miny, maxx, maxy = bounds
    ratios = []

    for y in (miny, (miny + maxy) / 2, maxy):
        x1, x2 = minx, minx + (maxx - minx) * 0.1
        lon1, lat1 = to_wgs.transform(x1, y)
        lon2, lat2 = to_wgs.transform(x2, y)
        _, _, true_m = geod.inv(lon1, lat1, lon2, lat2)
        grid_m = x2 - x1
        ratios.append(grid_m / true_m)

    spread = max(ratios) / min(ratios) - 1
    honest = spread <= tolerance
    print(f"scale ratio across the extent: {min(ratios):.3f} โ†’ {max(ratios):.3f} "
          f"({100 * spread:.1f}% spread)")
    print("  a single scale bar is " + ("defensible" if honest else "NOT honest here"))
    return honest
>>> scale_bar_is_honest("EPSG:3857", (-1.1e6, 4.2e6, 3.5e6, 1.1e7))   # Europe
scale ratio across the extent: 1.223 โ†’ 2.886 (135.9% spread)
  a single scale bar is NOT honest here

>>> scale_bar_is_honest("EPSG:27700", (100000, 0, 700000, 1000000))   # Britain
scale ratio across the extent: 1.001 โ†’ 1.001 (0.0% spread)
  a single scale bar is defensible

>>> scale_bar_is_honest("EPSG:5070", (-2.4e6, 2.5e5, 2.3e6, 3.2e6))   # conterminous US
scale ratio across the extent: 0.992 โ†’ 1.017 (2.5% spread)
  a single scale bar is NOT honest here

The third result is the useful one: an equal-area projection across the width of the United States varies by 2.5%, which fails a 2% tolerance and is entirely acceptable for most purposes. The function does not decide for you; it tells you the number so you can.

Example 2 โ€” the provenance block every map should carry

def add_provenance(fig, *, sources, projection, made_on=None, licence=None,
                   fontsize=6, colour="#64748b"):
    from datetime import date
    lines = ["Source: " + " ยท ".join(sources),
             f"Projection: {projection}"]
    if licence:
        lines.append(f"Licence: {licence}")
    lines.append(f"Made: {made_on or date.today().isoformat()}")

    fig.text(0.01, 0.01, "\n".join(lines), fontsize=fontsize, color=colour,
             va="bottom", ha="left", linespacing=1.4)

Six point type in the corner, and it converts a picture into a citable figure. It is the highest value-per-pixel element on any map.

Example 3 โ€” an element budget, enforced

ELEMENT_COST = {          # approximate share of the figure each one consumes
    "title": 0.06, "legend": 0.10, "scale bar": 0.03, "north arrow": 0.02,
    "locator inset": 0.09, "graticule": 0.00, "provenance": 0.03,
}


def element_budget(elements, limit=0.25):
    used = sum(ELEMENT_COST[e] for e in elements)
    print(f"{'element':16} {'share':>6}")
    for e in sorted(elements, key=lambda e: -ELEMENT_COST[e]):
        print(f"{e:16} {100 * ELEMENT_COST[e]:5.0f}%")
    print(f"{'total':16} {100 * used:5.0f}%   "
          f"{'ok' if used <= limit else 'the apparatus is crowding the data'}")
    return used <= limit

The numbers are approximate by design. The point of the function is to force the list to be written down, at which point somebody usually removes two things.

Explanation

Why a scale bar is the element most often wrong

Scale bars feel like a basic courtesy, so they are added reflexively โ€” usually to a map drawn in whatever CRS the data arrived in, which is increasingly Web Mercator because that is what web basemaps use.

Web Mercator is conformal, which preserves shape locally and not distance globally. The measured ratios above are the consequence: at 52ยฐ north, a kilometre on the grid is 617 metres on the ground. A bar labelled "100 km" is right at the equator and nowhere else on the same map.

The fix is not a cleverer bar. It is to reproject for the extent โ€” an equidistant or equal-area projection chosen for the area โ€” or to state the scale in words with the latitude it applies to.

Why the north arrow survives on checklists

It is cheap to draw, it looks cartographic, and it was genuinely necessary on paper maps that could be rotated on a table or bound at an angle. On a north-up figure in a report it answers a question nobody has.

The test is whether removing it costs the reader anything. On a rotated site plan it does; on a national choropleth it does not.

Why provenance is the element people skip and should not

Source, date and projection are what let somebody else check the map, reproduce it, or decide whether it is still current. They are also what stop a figure being reused two years later as if it were fresh.

Unlike a north arrow, they cannot be inferred from the map itself. Once the figure leaves your machine, that information exists nowhere else.

Why the space argument is not fussiness

The apparatus competes with the data for a fixed area, and the ceiling is lower than it feels: a standard plotting area holds about 354 labels of 7 pt type before it is completely tiled, and a realistic map with white space carries closer to sixty.

Every element added takes from that budget. A legend, an inset and a title can easily consume a quarter of the figure, which is defensible when each one is needed and indefensible when they are there because a checklist said so.

Table of provenance fields: source, boundaries, projection and date, with examples.
It costs one line of 6 pt text and turns a picture into a citable figure.

Edge cases or notes

  • Interactive maps have different rules. A scale bar that updates with zoom is honest; a static one is not.
  • A title may live in the figure caption instead โ€” in a report, the caption is often the better place.
  • Legends for continuous data should show the range and the class breaks, not a smooth bar with no numbers.
  • "No data" needs its own legend entry, distinct from the ramp.
  • Insets need an extent rectangle on the main map, or the reader cannot connect them.
  • Neatlines are optional and often just a box around a figure that already has edges.
  • Attribution can be a licence requirement โ€” OpenStreetMap and many national datasets require it.
  • Check the elements survive export. A scale bar sized in points is wrong after a figure is scaled into a column.

FAQ

Does every map need a scale bar?

No โ€” and on many maps it is wrong. In Web Mercator at 52ยฐ north, grid distance overstates ground distance by a factor of 1.62, so one bar cannot be correct across a map of Europe.

Does every map need a north arrow?

Only if the orientation is not obvious: a rotated plan, a polar map, or a projection where meridians visibly converge. On a north-up national map it is furniture.

What should a map always include?

The data source, the date and the projection. They cannot be inferred from the image, and they are what make the figure citable and checkable.

When do I need a locator inset?

When the audience does not already know where the area is. It is a question about the audience, not about the map.

Should I add a graticule?

On small-scale maps and where coordinates will be read off the page, yes. On a district-level thematic map it is a grid of lines competing with the data.

How much of the figure should the apparatus take?

About a quarter at most. A legend, a title and an inset reach that quickly, which is why writing the list down usually results in something being removed.