Matplotlib fill area with different colors based on a value

I want to fill an area between two lines based on a 3rd value. This is the desired output: An area filled with different colors

This is what I did so far, based on the docs here.

self.axes.fill_between(x, y1, y2, color='cyan')

This is the result : The output of my code, an unicolor area between two lines

I have x, y1, y2, and a 4th vector containing values that determines the coloration of the area contained between the two lines.

How can I do that in matplotlib ?

Answer

You can color an image horizontally using the fourth array and then clip it by the polygon created via fill_between:

import matplotlib.pyplot as plt
import numpy as np

# first create some test data
x = np.linspace(0, 100, 200)
y1 = 10 + np.random.randn(200).cumsum()
y2 = 30 + np.random.randn(200).cumsum() / 5
fourth = np.random.randn(200).cumsum().cumsum()
fourth -= np.linspace(0, fourth[-1], 200) # make start and end equal

fig, ax = plt.subplots(figsize=(12, 3))
polygon = ax.fill_between(x, y1, y2, lw=0, color='none')
ax.margins(x=0.02)
xlim = ax.get_xlim()
ylim = ax.get_ylim()
verts = np.vstack([p.vertices for p in polygon.get_paths()])
filling = ax.imshow(fourth.reshape(1, -1), cmap='viridis', aspect='auto',
                    extent=[verts[:, 0].min(), verts[:, 0].max(), verts[:, 1].min(), verts[:, 1].max()])
filling.set_clip_path(polygon.get_paths()[0], transform=ax.transData)
ax.set_xlim(xlim) # the limits need to be set again because imshow sets zero margins
ax.set_ylim(ylim)
plt.tight_layout()
plt.show()

image clipped by fill_between