Cartographic palettes and colour harmonies

This story begins one day when I was assembling a map of the city of Edmonton, Alberta from OpenStreetMap data. It was going to be a big map, a 42″ (106 cm) wide poster for a wall.

OpenStreetMap colour palette

The data was good, but the standard OSM colours were not. They would work fine for a street map but, for a piece of art being seen all day in someone’s living space, there was an unpleasant amount of grey. Plus, the accents of pinky red and ochre, and the cold green parks, gave it a lack of colour harmony.

If you analyze the colour profile of this map, counting the number of pixels of each colour and assuming there are 12 colours being used, you can see that white and the first two greys occupy about 70% of the map surface. You’d not be wrong if you said, “That’s a grey map.”

Moreover, this colour palette does have any of the classic “harmonies” that we expect when we look for how colours work together in an image. (E.g., see here.) There’s no dominant point on the colour wheel, no complementary colour, no triadic distribution or analogous set. It’s not OpenStreetMap’s fault: this is just the colour mix that you get when you look at this specific framing of this city.

If we want the map to look harmonious, we need to think about two things. What colours are used? And what proportions are they used in?

For example, look at the 1986 map, below, of Central Asia from the Royal Geographic Society. My sense here is that the cartographers thought about the colours, their relationships to one another, and the percentages of the map they would occupy. Most of the colours are clustered around the green-yellow-orange side of the colour wheel, but there are a few complementary blues. There is enough green in India to showcase the yellows, oranges and browns of Tibet. The adjacent blobs of orange Tibetan highland and grey-brown Tarim Basin work well together. There’s a nice balance of values from very dark to white. There’s no particularly bright colour that draws the attention from other areas. It says “reference map,” rather than “map with a point to make.” Overall, it’s quite pleasant to look at.

Image Color Summarizer

It turns out that there’s an interesting tool for doing an initial analysis of a colour palette and the proportions of an image the different colours occupy. It’s called Image Color Summarizer and it comes to us courtesy of Martin Krzywinski at the BC Genome Sciences Centre. You go to and go to the Analyze tab. Upload your image and choose, say, 12 colour clusters and very high precision.

The software then reduces the number of colours in the image to (in this case) 12 , using an algorithm that shifts colours a minimum to fit them into 12 categories. It then gives you all sorts of great information. So here we have first an analysis of colours in the RGS map of Central Asia…

…and then my OSM map of Edmonton:

This is very useful for a quick look at colour proportions and interrelatedness between colours. You get each colour in hex, RGB, HSV and LCH, and the percentage of the image that it occupies.

You might have noticed, however, that Image Color Summarizer gave different results on my OSM map from the ones I showed at the beginning of this page. It ranked the two greys first, and then white, with the three totalling only 60% of the image. There are a number of reason for this, but one is that this software does have a shortcoming: even at the “very high” precision setting it reduces your image to 200 pixels wide before doing its analysis. This means that if you have tiny features, like small labels or trim lines running alongside roads, their contribution to the overall colour mix can be lost.

If you want to use Image Color Summarizer fairly often, I recommend you download the software (on the Download tab) and run it locally at the command line. It’s a PERL script. This both reduces the load on the BCGSC server that hosts it, and allows you to analyze images larger than 200 px wide. You can just use your own computing resources and just let it run all night! (Think about it, though: an image 1500 px wide will take 100 times longer to analyze than one which is 150 px wide.)

At this point you might think the problem is basically solved: we extracted a 12-colour palette and their proportions from a map whose colour harmony I like, and all we have to do is to apply those to my OSM map.

But it’s not so simple. First of all, the OSM map did not have a 12-colour palette. In fact, according to GIMP (Color>Info>Colorcube Analysis), it had 213,078 colours. And this shouldn’t be surprising: OSM Downloader generated scores of rules for styling its many lines and polygon types. And then when I exported the map out of QGIS, antialiasing produced even more colours.

Just a few of the polygon styling rules from OSM Downlaoder

Image Color Summarizer suggested a palette, but before it did that it had scaled the map image to a mere 200 pixels across, and then simplified it to 12 colours.

Working with the actual map (some 12600 pixels across) there are two possible ways we can go:

  1. We could take the finished map with its OSM colours, and a “model” image, simplify them both to a reasonable number of colours (say 12), and then do a 1-to-1 substitution based on the order of colours when they are ranked by percentage of image. Or…
  2. We could simplify the styling of the map within QGIS to, say, 12 colours, and then apply the colours we get from simplifying the model.

Let’s look at each of these in turn.

Replacing the colour palette of a finished map, using GIMP

This is certainly the easier way, but it may not give you the level of control you want.

GIMP has an excellent tool for simplifying an image to a set number of colours at Image > Mode > Indexed. It allows you to decide how many colours you want (we’ll use 12), and whether these can be dithered or not. Generally I do not use dithered, except sometimes I do.

Once you have reduced your map to 12 colours, you can see those colours by opening the Colormap dialogue (Windows > Dockable Dialogs > Colormap).

Unfortunately they are not ordered by how much of the image they represent. You have to determine this yourself, and it’s a bit clumsy. Have the Histogram dialogue open (Windows > Dockable Dialogs > Histogram) and right click each colormap colour in turn, taking “Select this colour.” The Histogram window will tell you how many pixels in the image are selected. I take notes into a spreadsheet and that gives me the table I showed above:

The top line, “Index” tells me the position of the colour in the original colormap, from 0 to 11. I then re-order the colourmap in descending order of “real estate” (that is, what percentage of the image is occupied by each colour), by right-clicking any colour and choosing “Rearrange colormap.” Now my colourmap looks like this:

At this point, white, the most common colour, is index 0; the two greys are indices 1 and 2; two greens are indices 3 and 4; and so on.

I do the same tedious process with my model image. I reduce it to 12 colours, I make notes on how much of the image each colour represents…

…and re-order its colormap correspondingly:

In order to substitute the new palette colours for the original colours I have to do one more preparatory step. I have to convert this GIMP colourmap into a GIMP palette. I do this by opening the Palette dialogue (Windows > Dockable Dialogs > Palettes), right-clicking it and taking “Import Palette.” I import the palette using the model image as source.

Finally, I can apply that palette to the original map by going to Colors > Map > Set Colormap, and choosing the palette I just imported.

And there it is.

RGS “Mountains of Central Asia” colour palette

Now, you can see right away that this is both successful and not exactly what we expected. The map has acquired the palette of the original image, and by a stroke of luck the North Saskatchewan River became a pale green, which actually works for a river. It looks pretty good! But, to be picky, it doesn’t exactly have the original colour proportions. As noted before, the RGS map has quite a bit of green in it (anchoring the lower left), but we didn’t get that much green.

The reason for this becomes apparent when we compare the original map image (left) with its indexed version (right)…

Yes, there were a lot of green pixels there, but the indexing process turned much of it into patches of yellow. This is a hazard of reducing the number of colours in an image.

Still, that was successful enough that I want to try extracting a colour palette and proportions from some non-map image, and seeing if I can apply those to my map. Let’s try—I don’t know—this Georgia O’Keefe painting of an iris:

Once reduced to 12 colours (I did use dithering here) the palette in descending order of pixels looks like this:

And the result looks like this:

Georgia O’Keefe “Light Iris” colour palette

Again, it’s basically right, although the overall colour signature isn’t quite as light as the original image. The palette is centred around many varieties of purple and white, with a bit of nearby blue, opposed by a small proportion of complementary yellows. Looking at the original Georgia O’Keefe painting, I’d expect a bit more of the bright yellow, but I see that this colour went into the pixels of small features like riverside bike paths, only visible when you get up close. I’d also expect a bit more black, but the black got shunted into the railways lines so is quite fragmented and not visible when you look at the map as a whole.

This points out another factor: the extracted colour palette and proportions only tell part of the story of how an image presents itself. Another important factor is whether a given colour is fragmented into many small pixel groups, or collected into one or two large swathes. Maps (at least urban maps) tend to have a lot of pixels dedicated to small labels or street lines, and the colours used here rarely declare themselves when you look at the whole map.

Designing the map to a specific palette from the start

Swapping in the colours from an image with good colour harmony, in order of prevalence, sort of works, but now let’s look at our other alternative. This is simplify the styling of the map within QGIS to, say, 12 colours, and then changing these colours before exporting the map.

One advantage of this was that I would be able to apply a new palette to my map carefully. I wanted, for instance, to be able to put dark colours where I needed dark colours (labels, high contrast borders), to pair related colours together (parks and their sports fields, or neighbourhoods and their buildings) and to deploy complementary colours to occupy features that would allow them to give just the right amount of zing to the overall impression.

I also wanted to avoid this sort of thing, where the label and its halo in the original OSM map were of contrasting values, but after GIMP swapped in a different colour palette they had similar values.

Text was indexed colour “8” in the original map (left), which was a dark, warm grey. Its halo was colour “5”, a light tan, and this resulted in good contrast. In the new palette (right), colour “8” was a dark blue, and colour “5” was an only slightly lighter teal; as a result, there was very little contrast.

QGIS has an excellent feature for building a map from a specific colour palette: Project Colors. This is under Project>Properties>Default Styles. Essentially, you define a colour palette, each colour having a text string to identify it.

These palettes can be saved (and imported) as .GPL text files. Then, when styling a feature, you don’t assign it just any old colour: you use a data-defined override to assign it one of the colours from the Project Colors list:

With this in place, when the Project Color with that name changes, all features tied to it change colour as well.

Unfortunately, QGIS does not automatically pick up the colours of a project and list them for you. I still went through the process of indexing the image in GIMP and entering those colours as project colours. I named them by the typical features that used them. Note that once you begin assigning project colours to features, you can’t change the names of the colours (e.g., “building, street casings”) because in the QGIS project file the colours used in feature styling are actually referred to by these names.

It took quite a while to go through all of the styling rules and style everything using only the 12 project colours. Pleasingly, it did not change the overall look of the map very much.

Then I made an alternate project palette from the 12 Georgia O’Keefe colours, not worrying too much this time about what percentage of the original image they occupied, but assigning them where I thought they would work best. It seemed like it might be time to let go of applying colours in the order of their prevalence, because it was not necessarily producing good effects.

And that produced this map:

Georgia O’Keefe “Light Iris” colour palette, version 2

It has to be said that this method gives much better control. Given the colours you want in your palette, you can move them around to different classes of features until they represent the right proportion of the image. You can alter them slightly. You can save palettes you like and then read them back in later. (Note: when you read in a .GPL colour file, QGIS appends them to the project colours. Then you have to select and then delete the previous project colours .)

Furthermore, once the initial work of styling the map to a certain number of colours is done (and I soon expanded to 18 project palette colours, since 12 is pretty tight!), the process of going from a new model image…

“Early winter”

…to its palette…

…to a new version of the map…

“Early Winter” colour palette

… is quite fast. What made this quick was that, after GIMP indexed the photograph to 18 colours, I took a screenshot of its colormap, rotated that 90°, and then used the QGIS Colour Picker tool to assign these colours to the project palette. (And then saved that palette.)

A final piece of colour palette inspiration was this map from the Second Military Survey of the Habsburg empire, Galicia and Bucovina (1861–1864), which I obtained by screenshot from

I love its muted but warm bronze tones, the pale green for flatlands, and the thin blue stream running through it. (This is the area today around Verkhovyna/Верховина, Ukraine). It also has a bit of complementary colour: some barely noticeable red elevation notations.

GIMP simplified this map to these 18 colours, which do capture the overall palette, but miss the red and the blue:

It seemed reasonable to just add them in:

And that produced this:

“Second Military Survey of the Habsburg Empire” colour palette

In summary

I’m sold on the second method: designing a map around a specific palette, and then swapping in alternate palettes with good colour harmonies stolen from other images. This was the approach that gave more satisfying results. You do more work up front, but in the process you also come to understand the underlying colour structure of your map: which colours are adjacent to which, which need to be related, which are fragmented and which occur in large continuous fields.

An 18-colour palette was much more reasonable than 12-colour palette. For this kind of urban map I calculated that I needed:

  • one colour with four different values. In the original map these were the greys: residential zones, buildings, neighbourhood labels.
  • other light-dark pairs, maybe six of these. For example you need a light blue and dark blue (bike routes and water), a light red and a dark red (motorway fill, motorway casing), a light yellow and a dark yellow (secondary road fill, secondary road casing), etc.
  • black
  • white

The GIMP is an invaluable tool in assessing the colours of an image. If nothing else, it can help you quantify the “colour signature” of an image.

If the overall colour harmony of your map matters (and it should!), palette-cloning and palette-switching are powerful tools. You could tweak your map so its colours reflect the natural colours of the area depicted. You could harmonize a map’s colours with those of the larger display in which it is being placed. You could deliberately echo the colours of an earlier map.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s