Set colormap limits when creating m colors
Emma Farnan
on 28 Feb 2024
Several of the colormaps are great for a 256 color surface plot, but aren't well optimized for extracting m colors for plotting several independent lines. The issue is that many colormaps have start/end colors that are too similar or are suboptimal colors for lines. There are certainly many workarounds for this, but it would be a great quality of life to adjust that directly when calling this.
Example:
x = linspace(0,2*pi,101)';
y = [1:6].*cos(x);
figure; plot(x,y,'LineWidth',2); grid on; axis tight;
And now if I wanted to color these lines, I could use something like turbo(6) or gray(6) and then apply it using colororder.
colororder(turbo(6))
But my issue is that the ends of the colormap are too similar. For other colormaps, you may get lines that are too light to be visible against the white background. There are plenty of workarounds, with my preference being to create extra colors and truncate that before using colororder.
cmap = turbo(8); cmap = cmap(2:end-1,:); % Truncate the end colors
figure; plot(x,y,'LineWidth',2); grid on; axis tight;
colororder(cmap)
I think it would be really awesome to add some name-argument input pair to these colormaps that can specify the range you want so this could even be done inside the colororder calling if desired. An example of my proposed solution would look something like this:
cmap = turbo(6,'Range',[0.1 0.8]); % Proposed idea to add functionality
Where in this scenario, the resulting colormap would be 6 equally spaced colors that range from 10% to 80% of the total color range. This would be especially nice because you could more quickly modify the range of colors, or you could set the limits regardless of whether you need to plot 3, 6, or 20 lines.
6 Comments
Hi Emma,
You bring up a good point about how indexing into a colormap doesn't produce the most distinct colors. This is by design for two different workflows where your data is either discrete or continuous. Starting in 23b, we introduced a suite of new named color orders which were designed to be used for discrete data whereas the named colormaps you mentinoed like turbo and gray were not. In this blog post, you can see the author leverages the SeriesIndex which is a property on objects meant to leverage colororder for discrete data sets. A scatter and line object share a SeriesIndex if they are part of the same group.
As you suggested, there are current workarounds to the problem you pose but an enhancement to to make this color interpolation easier is reasonable. I just wanted to chime in to let you know that the color order colors and colormap colors were designed differently.
You are getting at an important distinction between a color map and a color order.
- Our color maps are designed to aid in the interpretation of continuous numeric data.
- Our color order colors are designed to differentiate a small number of discrete groups.
The very nature of a color map (like turbo or parula) is so that neighboring colors are similar and that the list of colors form a continuous transition from one color to another. That is so that when you use it to color a range of continuous numeric values, values that are close to one another are similar colors and values that are far from one another are different colors. In addition, for a well designed color map, two sets of values that are equal distance from each other will be equally distinct colors.
For example, if you have the values [1 2 100 101].
- The values 1 and 2 should be similar colors.
- The values 100 and 101 should be similar colors.
- The values 1 and 2 should be distinct colors from 100 and 101.
- Ideally, the perceptual difference in color between 1 and 2 should be similar to the perceptual difference in color between 100 and 101.
Due to this design, it turns out that it is relatively easily to programmatically/algorithmically generate a color map with an arbitrary number of colors, but using a color map for a small number of colors is unlikely to create colors that are easily distinguishable from one another, so they don't work well as color orders.
Color order colors, on the other hand, are intentionally chosen so that neighboring colors are distinct, so that when you plot two lines (for example) you can easily tell them apart. It turns out that it is actually quite difficult to generate an arbitrary number of colors that are each visually distinct from each other and asthetically pleasing. Most algorithms I've seen (see ColorBrewer for example) max out at less than a dozen colors, because beyond that it gets really difficult to pick visually distinct colors algorithmically. By the way: At least two users (here and here) have attempted to make Color Brewer available in MATLAB.
With MATLAB itself, we've had a large collection of color maps for a long time (see the colormap doc page for a list). We recently released a small number of new color orders (see the orderedcolors page for a list).