How can I create matplotlib line with z dependent fill color

Viewed 305

How can I draw a x-y line with matplotlib that has a fill-between color which depends on a third variable z? (where z is of same length as x and y).

I would like something like this:

enter image description here

What I am getting:

enter image description here

Sample code looks like this:

import numpy as np
import matplotlib.pyplot as plt

cm = plt.get_cmap('gist_rainbow')

x = np.linspace(0, 10, 100)
y = np.sin(x) + 1.3
z = 0.5*(np.cos(x) + 1.0)

fig = plt.figure(111)
ax = plt.axes(xlim=(0.0, 10.0), ylim=(0.0, 3.0))
line, = ax.plot([], [], lw=2)

line.set_data(x, y)
ax.fill_between(x, y, interpolate=True, color= cm(z))

plt.show()

I have tried with and without interpolate=True but makes no difference here.

Have scanned similar questions/answers but haven't found anything that would help me solve this. Any suggestions would be much appreciated.

1 Answers

With imshow() and setting the x of the curve as the horizontal extent, you can draw a correctly colored rectangle covering the curve. That image can be clipped with a polygon created by fill_between().

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch

cmap = plt.get_cmap('gist_rainbow')

x = np.linspace(0, 10, 100)
y = np.sin(x) + 1.3
z = 0.5 * (np.cos(x) + 1.0)

fig, ax = plt.subplots()
ax.set_xlim(0.0, 10.0)
ax.set_ylim(0.0, 3.0)
ax.plot(x, y, lw=2)

poly = ax.fill_between(x, 0, y, color='none')
img = ax.imshow(z.reshape(1, -1), extent=[x[0], x[-1], 0, y.max()], cmap=cmap, aspect='auto', interpolation='bilinear')
clip_poly = PathPatch(poly.get_paths()[0], transform=ax.transData)
img.set_clip_path(clip_poly)
plt.colorbar(img, ax=ax)
plt.tight_layout()
plt.show()

resulting plot

Related