Daily Archives: 2015-11-16

Brunel 0.8: Enhanced Color mapping

Published by:

The two main new features of Brunel 0.8 are an enhanced UI for building (as described by Dan) and a through re-working of our code for mapping data to color. This post is going to talk about the latter — with a lot of examples!

Twelve Ways to Color Africa

The data set we are using is from http://opengeocode.org. We took a subset of the countries and data columns (CSV data)  for this exercise.

These examples are using some prototype code for geographic maps that we are going to introduce into a later version of Brunel (probably v1.0, slated for January), but maps looks so nice, we wanted to use them for this article. Please do not depend on the currently functionality — consider this “advance preview” and highly subject to change.

Because there are a lot of maps, these are not live versions, but static images — click on them to open up a Brunel editor window where you can see it live and make changes.

The Brunel language reference describes the improvements to the color command in detail. Here we just show examples!

Categorical Colors

africa2africa3

The above two images are created by the following Brunel:

  • map(‘africa’) x(name) color(language) label(iso) tooltip(#all) style(‘.label{opacity:0.5;text-shadow:none}’)
  • map(‘africa’) x(name) color(language:[white, nominal]) label(iso) tooltip(#all) style(‘.label{opacity:0.5;text-shadow:none}’)

For all our examples, the only changes are the color statement, so from now on we’ll just refer to the color command.

If you use a simple color command, as in the first example, Brunel chooses a suitable palette. In this case “language” is a categorical field, so it chooses a nominal palette. This is a palette of 19 colors chosen to be visually distinct.

The second example specifies which colors we want in the output space. The first category in the “language” field is special, so we ask for a palette consisting of white, then all the usual colors from the nominal palette.

africa4Because we know the data well, we can hand-craft a color mapping here that reflects the language patterns better. I used color(language:[white, red, yellow, green, cyan, green, green, blue, blue, blue, blue, gray, gray, gray, gray, gray])  to use red for lists containing Arabic, green when they contain English, and blue when they contain French. I mixed the colors to show lists where the languages are mixed.

The geographical similarities in languages can be seen pretty easily in the chart, but the colors are a bit bright. Which leads to the following …

For areas and “large” shapes, Brunel automatically creates muted versions of colors, so names like “red” and “green” are less visually dominant and distracting. This can be altered by adding a “=” to the list of colors, which means “leave the colors unmuted”, or a series of asterisks, which means “mute them more”. Here are a couple of examples, using the same basic palette as the previous one

africa5africa6

africa7If you have a smaller fixed number of categories in your field, you can use palettes carefully designed to work well for that number. Rather than provide them in Brunel, our suggestion is to go directly to a site that allows you to select them (Cynthia Brewer’s site ColorBrewer is  the standout recommendation) and copy the array of color codes and paste them directly into the Brunel code.

For the example on the right, we did exactly that, using en:[‘#beaed4’, ‘#7fc97f’]) as out colors (the quotes are optional in this list)

Color Ranges

For numeric data, we want to map the data values to a smoothly changing range of values. So, instead of defining individual values, we define values which are intermediate points on a smoothly changing scale of colors. We do this using the same syntax pattern as for categorical data. We are using the latitude of the capital city to color by, rather than a more informative variables, so the color changes can be seen more clearly.

africa8africa13

On the left we specified color as color(capital_lat) so we get Brunel’s default blue-red sequential scale. This uses a variety of hues, again taken from ColorBrewer, to provide points along a linear scale of color. On the right we use an explicit color mapping from ColorBrewer, color(capital_lat:[‘#8c510a’, ‘#bf812d’, ‘#dfc27d’, ‘#f6e8c3’, ‘#f5f5f5’, ‘#c7eae5’, ‘#80cdc1’, ‘#35978f’, ‘#01665e’]), where we simply went to the site, found a scale we liked and used the export>Javascript method. Note that Brunel will adapt to to the number of colors in the palette automatically.

africa9africa10

The above two charts show the difference between asking for color(capital_lat:reds) and color(capital_lat:red). When a plural is used, it gives a palette that uses multiple hues, with the general tone of the color being requested. With a  singular color request, you only gets shades of that exact hue. Generally we would recommend the former unless you have some specific reason to need the single-hue version.

africa11africa12

We can specify multiple colors in the same way as we do for categorical data, using capital_lat:[purpleblues, reds]) on the left and capital_lat:[blue, red]) on the right. When we have exactly two colors defined, we stitch them together, running through a neutral central color, to make a diverging color scale that highlights the low and high values of the field.

Summary

Mapping data to color is a tricky business, and in version 0.8 of Brunel our goal is twofold: To ensure that if you only specify a field, a suitable mapping is generated, and second, to allow the output space of colors to be customized for user needs. In future versions of Brunel we will add mapping for the input space, so, for example, we could tie the value mapped to white in the last example to be the equator, not simply midway through the data range. Look for that in a few months!