# In MATLAB, it’s colormaps all the way down

My overriding emotion, working in R, has been incomprehension: incomprehension at the gallery of ugly gnomes that populate the namespace and worried puzzlement over the strange incantations required to get them to dance in a statistically harmonious way. But all that aside, I resolved, joining the group, to put aside my misgivings and give the gnomes another try.

Soon, I found myself engaged in a reassessment of my life choices. I realized that life’s too short to spend it tickling gnomes – especially when only one of them knows how to do linear regression, but he won’t tell you your p value unless you give him the right kinds of treats. I fired up MATLAB and I haven’t looked back.

However, there was issue of continued perplexity, and I’m not referring to why MATLAB insists on shouting itself at you. I need to make a lot of 2-D plots of protein distance matrices. The trouble is that I like to highlight parts of them, and that’s not straightforward in MATLAB. Let’s have a look at an example:

```>> dists=dlmread('1hel.distances');
>> colormap gray;
>> imagesc(dists>8);
>> axis square;```

Now, let’s load up a set of residues and try to overlay them on top of the first image:

```>> resn=dlmread('1hel.resn');
>> hold on
```

So far, so easy. To review the main points:

`mask` is a matrix which has a one at all the pixels that we want to highlight. But we use `imagesc(1-mask)` because the gray colormap displays black at 0 and white at 1. If we did `imagesc(mask)`, we would end up with grey everywhere and white only where we hoped to highlight – the opposite effect from the one that we sought.

`AlphaData` is a property which sets the transparency of the image. We want the image to be fully transparent where `mask` is 0 – so as not to fog out the underlying image – and partially transparent where `mask` is 1. `0.5*mask` is a matrix which is 0.5 everywhere that `mask` is 1 and 0 everywhere else.  If we set `0.5*mask` as the `AlphaData` property, then the colour we add will be at half transparency and the white areas will be fully transparent.

But this isn’t a very pleasant image. We want to be able to highlight the regions in some colour other than grey. Let’s try.

```>> close all
>> imagesc(dists>8)
>> colormap gray
>> axis square
Error using image
There is no ColorMap property on the Image class.

Error in imagesc (line 39)
hh = image(varargin{:},'CDataMapping','scaled');
```

No luck! What’s more, setting the colormap between calls to `image()` and `imagesc()` also doesn’t work. Here’s the problem: the `colormap` is a property of the figure, not the data. (More precisely, it is not a property of the MATLAB axes.) When you change the `colormap`, you change the colors of every datapoint in the image.

# The fix

MATLAB’s `colormap` mechanism is just simple enough to be confusing. MATLAB stores colours as 1×3 vectors, where each element in the vector is the proportion of red, green, or blue, respectively. [1 1 1] is white, [0 0 0] is black, and [1 0 0] is a frightfully iridescent red. A colormap is just a list of colors – 64 will normally do – which change smoothly from from one colour to another. To have a look at the built-in MATLAB colormaps, see here.

`image` rounds every value in the matrix to the nearest whole number (call that number `i`)  and plots that pixel with the color given by `colormap(i,:)`. Zero or below gets the first entry in the `colormap` and any index higher than the maximum is displayed with the last color in the `colormap`. So: if we construct a new `colormap` by concatenating two colormaps – the first running from rows 1 to 64 and the second running from 65 to 128 – if we scale our data so that the minimum is 65 and the maximum is 128, the data will never use the first set of colors. And, likewise, if we scale so that the lowest value is 1 and the highest is 64, we will use the first colormap. This seems like the sort of thing that we could manage automatically – and should, in fact. So I set myself to replace `image` and `imagesc` so that they would accept a `ColorMap` parameter.

How would it work?

```>> colormap bone
>> imagesc(dists>8)
>> hold on
• `image` is implemented in the MATLAB Java source code, but `imagesc` is a wrapper to `image`, written directly in MATLAB code. Therefore, overloading `image` requires the new function to be placed in a special directory called `@double`, while `imagesc` can be placed anywhere (except it cannot be placed in `@double`). If you then want to call the original version of `image()`, you can use `builtin(‘image’,arg1,arg2,…)`, whereas if you want to call the original `imagesc`, it is a right pain. Instead, I used `type imagesc` to extract the source of `imagesc` and I modified that source directly – obviating any need to call the original `imagesc`. For reference, though, the most efficient way works out to be to find the function with `which('imagesc')`, `cd` into the containing directory, create a function handle to `imagesc`, and then `cd` out. As I said, it’s a mess.
• These edits break colorbars. I added a spacer entry in each colormap which stores the maximum and minimum ‘real’ values of the data – in case that is useful for when I get around to extending `colorbar`. colormap entries must be inside [0,1] so these data are stored in the first twelve decimal places of the colormap entries: a strange burlesque on floating points. It’s a hack, but for my purposes it works.
• In addition to the standard colormaps, I often require a mask in a particular color. For this purpose it helps to have a `colormap` that smoothly varies from white to the color in question. It actually doesn’t matter if it varies from white or any other color – ultimately, I only use the full colour value, since I set the transparency of all other pixels to maximum – but either way, passing the colour on [0,1] scale or [0,255] scale sets a `colormap` which varies from white to that color.
The code is available on MATLAB File Exchange at this link and is installable by copying `imagesc.m``bootleg_fp.m`, and the directory `@double` into your working directory. The idea to concatenate colormaps is widely available online – for example, here.