2025, Dec 22 15:00
How to Extract RGB Values from Matplotlib LinearSegmentedColormap (PiYG) by Sampling with NumPy
Extract RGB from matplotlib LinearSegmentedColormap (PiYG) by sampling 0–1 with numpy.linspace and converting to 0–255. Works for ListedColormap too in Python.
Extracting RGB values from matplotlib colormaps is trivial when you work with discrete palettes, but it becomes less obvious for continuous gradients. If you rely on the colors attribute, the approach breaks for LinearSegmentedColormap instances like PiYG or hsv. Here’s how to get the same result reliably without guessing or reverse engineering.
When the direct approach works — and when it doesn’t
For a ListedColormap you can iterate through the predefined color entries and scale each channel to 0–255. A minimal pattern looks like this:
for idx in range(0, 255, 1):
r_int = int(255 * palette.colors[idx][0])
g_int = int(255 * palette.colors[idx][1])
b_int = int(255 * palette.colors[idx][2])
This pattern assumes the colormap exposes a colors attribute. LinearSegmentedColormap does not, so indexing into a non-existent list won’t work.
What’s really going on
ListedColormap stores a finite list of colors. LinearSegmentedColormap represents a continuous mapping instead; there are no pre-baked RGBs to index. There aren’t any attributes or methods on LinearSegmentedColormap analogous to colors, but you can still obtain as many colors as you need by sampling the colormap over the [0, 1] domain and converting the 0–1 floats to 0–255 integers.
Sampling a LinearSegmentedColormap
The most direct way is to generate evenly spaced samples with numpy, feed them to the colormap, take the first three channels (RGB), and optionally scale to 8-bit integers.
import matplotlib.pyplot as plt
import numpy as np
cmap_ref = plt.get_cmap("PiYG")
steps = 256
float_samples = [cmap_ref(t)[:3] for t in np.linspace(0, 1, steps)]
rgb_series = [(int(r * 255), int(g * 255), int(b * 255)) for r, g, b in float_samples]
The colormap returns RGB values in the 0–1 range. The tuple conversion replicates the integer 0–255 convention when needed.
You can also pass the whole array of positions to the colormap in one go, skipping the inner iteration and then converting to 0–255:
import matplotlib.pyplot as plt
import numpy as np
cmap_ref = plt.get_cmap("PiYG")
steps = 256
rgba_grid = cmap_ref(np.linspace(0, 1, steps))
rgb_series = [(int(r * 255), int(g * 255), int(b * 255)) for r, g, b, _ in rgba_grid]
Why this matters
Different matplotlib colormap classes expose different capabilities. If you rely on a property that exists only for discrete palettes, your code will silently break on continuous ones. Sampling normalizes your workflow: any colormap can be turned into a stream of RGB triplets at whatever resolution your application requires.
Conclusion
If you need raw RGBs from a LinearSegmentedColormap, don’t look for a colors attribute. Sample the colormap over [0, 1] using numpy.linspace, retrieve the RGB channels, and convert to 0–255 integers only if your downstream code expects that format. This keeps the logic consistent across both ListedColormap and LinearSegmentedColormap and avoids brittle assumptions about internal attributes.