Smooth colormap in matplotlib
15:14 09 Feb 2026

Question:

How can you make a colormap in matplotlib to render smoothly on a display?

Let me clarify. This is the code:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.colors as mcolors
import matplotlib as mpl
from math import trunc

def wav2RGB(Wavelength):
    Gamma = 0.80
    IntensityMax = 255.0
    def Adjust(Color, Factor):
        if Color == 0.0:
            return 0.0
        else:
            return round(IntensityMax * (Color * Factor)**Gamma)
    if 380 <= trunc(Wavelength) and trunc(Wavelength) <= 439:
        Red = -(Wavelength - 440.0) / (440.0 - 380.0)
        Green = 0.0
        Blue = 1.0
    elif 440 <= trunc(Wavelength) and trunc(Wavelength) <= 489:
        Red = 0.0
        Green = (Wavelength - 440.0) / (490.0 - 440.0)
        Blue = 1.0
    elif 490 <= trunc(Wavelength) and trunc(Wavelength) <= 509:
        Red = 0.0
        Green = 1.0
        Blue = -(Wavelength - 510.0) / (510.0 - 490.0)
    elif 510 <= trunc(Wavelength) and trunc(Wavelength) <= 579:
        Red = (Wavelength - 510.0) / (580.0 - 510.0)
        Green = 1.0
        Blue = 0.0
    elif 580 <= trunc(Wavelength) and trunc(Wavelength) <= 644:
        Red = 1.0
        Green = -(Wavelength - 645.0) / (645.0 - 580.0)
        Blue = 0.0
    elif 645 <= trunc(Wavelength) and trunc(Wavelength) <= 780:
        Red = 1.0
        Green = 0.0
        Blue = 0.0
    else:
        Red = 0.0
        Green = 0.0
        Blue = 0.0
    # Let the intensity fall off near the vision limits
    if 380 <= trunc(Wavelength) and trunc(Wavelength) <= 419:
        factor = 0.3 + 0.7*(Wavelength - 380.0) / (420.0 - 380.0)
    elif 420 <= trunc(Wavelength) and trunc(Wavelength) <= 700:
        factor = 1.0
    elif 701 <= trunc(Wavelength) and trunc(Wavelength) <= 780:
        factor = 0.3 + 0.7*(780.0 - Wavelength) / (780.0 - 700.0)
    else:
        factor = 0.0
    R = Adjust(Red, factor)
    G = Adjust(Green, factor)
    B = Adjust(Blue, factor)
    return [int(R), int(G), int(B)]

def generateColor(color):
  nstep = 1000
  minW = 380
  maxW = 780
  bandW = maxW - minW
  colorTuple = ()
  for i in range(nstep + 1):
    wlength = minW + i * bandW / nstep
    colorTuple += ((1.0 * i / nstep, wav2RGB(wlength)[color] / 255.0, wav2RGB(wlength)[color] / 255.0),)
  return colorTuple

def generateGradient():
  return {'red':  generateColor(0),
          'green': generateColor(1),
          'blue':  generateColor(2)}




cmaps = {}

gradient = np.linspace(0, 1, 256)
print (gradient)
gradient = np.vstack((gradient, gradient))


def plot_color_gradients(category, cmap_list):
    # Create figure and adjust figure height to number of colormaps
    nrows = len(cmap_list)
    figh = 0.35 + 0.15 + (nrows + (nrows - 1) * 0.1) * 0.22
    fig, axs = plt.subplots(nrows=nrows + 1, figsize=(6.4, figh))
    fig.subplots_adjust(top=1 - 0.35 / figh, bottom=0.15 / figh,
                        left=0.01, right=0.99)
    axs[0].set_title(f'{category} colormaps', fontsize=14)

    for ax, name in zip(axs, cmap_list):
        if not (name == 'visibleSpec'):
            ax.imshow(gradient, aspect='auto', cmap=mpl.colormaps[name])
            ax.text(-0.01, 0.5, name, va='center', ha='right', fontsize=10,
                    transform=ax.transAxes)
        else:
            ax.imshow(gradient, aspect='auto', cmap=visibleSpec)
    

    # Turn off *all* ticks & spines, not just the ones with colormaps.
    for ax in axs:
        ax.set_axis_off()
    
    
    

    # Save colormap list for later.
    cmaps[category] = cmap_list


visibleSpec = mcolors.LinearSegmentedColormap('visible', generateGradient())
print (f"Length of generateColor(0) is {len(generateColor(0))}")
print (f" Length is {visibleSpec.N}")
plot_color_gradients('Perceptually Uniform Sequential',
                     ['viridis', 'plasma', 'inferno', 'magma', 'cividis','visibleSpec'])



plt.show()

This code displays the following:

Code result

The last colormap ,at the bottom, it is one custom created to show a spectrum. As you can see it has many color gradients and at that size it shows smoothly.

But if I enlarge the window on a 4k monitor here is a 1:1 crop and you can see it doesn't have smooth gradients when shown on a big monitor.

1:1 crop

My first ideea was to make a more detailed colormap but it seems that LinearSegmentedColormap cannot have more than 256 colors.

Any idea how to have smooth gradients with a colormap in matplotlib?

python matplotlib colormap