Creating Block Palettes with Glasbey

It is often useful to group categories together into groups and create a colour palette such that each group has different shades of a given colour, and distinct groups have shades of distinct colours. This can be done by gluing together discrtizations of continuous linear palettes – but that still leaves the problem of selecting distinct linear palettes. The glasbey library provides a an easy way to create such palettes, using techniques from the paper Colour Displays for Categorical Images by Glasbey, Heijden, Toh and Gray to provide visual distinctiveness between blocks. To demonstrate this in action we’ll need to import the glasbey library, and to visualize the palettes we create we will use seaborn.

[1]:
import glasbey
import seaborn as sns

sns.set()

To create a palette with blocks such that each block is built around a main colour, and distinct blocks have visually distinct colours we can call the create_block_palette function. The function has a single mandatory argument: a list of block sizes. For example, to create a block palette of twelve total colours in three blocks where each block has four colours we would call create_block_palette as follows:

[2]:
glasbey.create_block_palette([4, 4, 4])
[2]:
['#6d0004',
 '#ae1414',
 '#e35d2d',
 '#f79645',
 '#0400ba',
 '#0c4deb',
 '#4d96f7',
 '#86bef3',
 '#002d00',
 '#005900',
 '#418e0c',
 '#71b61c']

To see what this looks like we can visualize the resulting palette using seaborn’s palplot function.

[3]:
sns.palplot(glasbey.create_block_palette([4, 4, 4]))
_images/creating_block_palettes_5_0.png

An example of where such a palette might be useful is the well-known 20-newsgroups dataset, a classic dataset for NLP problems. The dataset collects messages from twenty different newsgroups, with the usla problem being that of successfully predicting the newsgroup of messages. Visualizing the dataset is quite common (see here and here and here for some examples). The first problem is that it is rare to find palettes with 20 distinct colours. The second catch is that the newsgroups themselves have somewhat overlapping topics. We can group them as follows:

Computers: * comp.graphics * comp.os.ms-windows.misc * comp.sys.ibm.pc.hardware * comp.sys.mac.hardware * comp.windows.x

Science: * sci.crypt * sci.electronics * sci.med * sci.space

Politics: * talk.politics.guns * talk.politics.mideast * talk.politics.misc

Religion: * alt.atheism * soc.religion.christian * talk.religion.misc

Sports: * rec.sports.baseball * rec.sports.hockey

Cars and motorcycles: * rec.autos * rec.motorcycles

For Sale: * misc.forsale

Ideally we would have a main colour for each group, and distinguish by variations of that colour within each group. The result would be a palette with blocks of various sizes etc. The create_block_palette is ideal for this as we simply hand it the various sizes of blocks we will need, and can then map the different newsgroups to colours in the relevant blocks. An example block palette for 20-newsgroups might be as follows:

[4]:
sns.palplot(glasbey.create_block_palette([5, 4, 3, 3, 2, 2, 1]))
_images/creating_block_palettes_7_0.png

As with the other glasbey functions there are a number of options to tweak and fine-tune the aesthetic with bounds on lightness, hue and chroma. This makes it easy to tweak the created palette to meet your exact aesthetic needs realtively quickly and easily.

[5]:
sns.palplot(
    glasbey.create_block_palette(
        [5, 4, 3, 3, 2, 2, 1],
        lightness_bounds=(15, 90),
        chroma_bounds=(0, 40)
    )
)
_images/creating_block_palettes_9_0.png

It is worth noting that strict bounds, particularly on lightness, can make it hard for the optimizer to successfully choose colours in thematiuc ranges, resulting in bizarre colour choices – if that happens consider opening up the bounds somewhat to allow more options for the optimizer.

Another example of a good use case can be seen in the palette “Paired” from ColorBrewer. This is a popular palette, not least because it has twelve colours (more than many other pre-defined palettes) – it also pairs up colours, with one light and one dark version of each colour in the palette…

[6]:
sns.palplot(sns.color_palette("Paired", 12))
_images/creating_block_palettes_11_0.png

But that’s only good if you have pairs of categories. Have you ever wanted a “Tripled” palette? We can easily generate a twelve colour palette with triples of each hue by simply specifying blocks of three (and we can always tweak aesthetics as above)

[7]:
sns.palplot(glasbey.create_block_palette([3, 3, 3, 3]))
_images/creating_block_palettes_13_0.png

But why stop at twelve? We can just as easily generate a nice looking twenty-one colour palette based around triples…

[8]:
sns.palplot(glasbey.create_block_palette([3, 3, 3, 3, 3, 3, 3]))
_images/creating_block_palettes_15_0.png

Hopefully you can already think of some potential use-cases for block palettes in your own work – and now you have the tools to easily build and tweak them yourself… or even create them on the fly as needed.