The goal is to fill the space between two arrays y1
and y2
, similar to matplotlib\'s fill_between. But I don\'t want to fill the space with a polyg
I wrote a little function which takes two arrays y1
, y2
(x1
, x2
are optional)
and connects their data points vertically.
def draw_lines_between(*, ax, x1=None, x2=None, y1, y2, color_list=None, **kwargs):
assert len(y1) == len(y2)
assert isinstance(color_list, list)
n = len(y1)
if x1 is None:
x1 = np.arange(n)
if x2 is None:
x2 = x1
if color_list is None:
color_list = [None for i in range(n)]
elif len(color_list) < n:
color_list = [color_list] * n
h = np.zeros(n, dtype=object)
for i in range(n):
h[i] = ax.plot((x1[i], x2[i]), (y1[i], y2[i]), color=color_list[i], **kwargs)[0]
return h
import matplotlib.pyplot as plt
import numpy as np
n = 10
y1 = np.random.random(n)
y2 = np.random.random(n) + 1
x1 = np.arange(n)
color_list = [str(x) for x in np.round(np.linspace(0., 0.8, n), 2)]
fig, ax = plt.subplots()
ax.plot(x1, y1, 'r')
ax.plot(x1, y2, 'b')
draw_lines_between(ax=ax, x1=x1, y1=y1, y2=y2, color_list=color_list)
Using a LineCollection could be handy if there are lots of lines in the game. Similar to the other answer, but less expensive:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
def draw_lines_between(*, x1=None, x2=None, y1, y2, ax=None, **kwargs):
ax = ax or plt.gca()
x1 = x1 if x1 is not None else np.arange(len(y1))
x2 = x2 if x2 is not None else x1
cl = LineCollection(np.stack((np.c_[x1, x2], np.c_[y1, y2]), axis=2), **kwargs)
ax.add_collection(cl)
return cl
n = 10
y1 = np.random.random(n)
y2 = np.random.random(n) + 1
x = np.arange(n)
color_list = [str(x) for x in np.round(np.linspace(0., 0.8, n), 2)]
fig, ax = plt.subplots()
ax.plot(x, y1, 'r')
ax.plot(x, y2, 'b')
draw_lines_between(ax=ax, x1=x, y1=y1, y2=y2, colors=color_list)
plt.show()