I currently have a curve defined by (x_orig, y_orig), and I want to plot the shaded region between two new curves defined by (x_orig - c, y_orig) and (x_orig + c, y_orig). When using matplotlib's fill_betweenx(), it does most of what I want, except when the two curves have opposite signs of their slope, they cross each other and there is nothing filled between them. I actually want the full space between the two filled. Imagine you grab the line (x_orig - c, y_orig) and drag it to the right to (x_orig + c, y_orig), I want to shade all of that area. I want to find the points that define the upper and lower shaded region so that I can additionally mask scatter points that happen to be in there.
I originally wrote an overcomplicated function that mostly does what I want, but it doesn't correctly handle the areas where the lines switch slope. Is there a more "pythonic" way of doing something that I want that isn't needlessly complicated?
def shaded_region(x_left, x_right, y_left, y_right):
y_upper = []
y_lower = []
y_lower.append(y_left[0])
y_upper.append(y_left[0])
#
s = np.sign((y_left[1] - y_left[0]))
#
x_new = []
x_new.append(x_left[0])
#
for i in range(0, len(x_left)-1):
m = (y_left[i+1] - y_left[i])
s_new = np.sign(m)
#
if s_new == s:
if m < 0:
y_upper.append(y_left[i])
y_lower.append(y_left[i+1])
if m > 0:
y_upper.append(y_left[i+1])
y_lower.append(y_left[i])
x_new.append((x_left[i+1]+x_right[i])/2)
else:
p1 = np.array([x_left[i+1], y_left[i+1]])
p2 = np.array([x_left[i], y_left[i]])
p3 = np.array([x_right[i], y_right[i]])
p4 = np.array([x_right[i-1], y_right[i-1]])
#
# print(i)
# print(p1,p2,p3,p4)
intersection = seg_intersect(p1, p2, p3, p4)
x_new.append(intersection[0])
#
if (s_new > 0) and (s < 0):
y_upper.append(intersection[1])
y_lower.append(np.min((y_right[i], y_right[i-1])))
dx = (intersection[0]-x_left[i])
x_new.append(intersection[0]+dx)
y_upper.append(y_left[i+1])
y_lower.append(y_left[i])
if (s_new < 0) and (s > 0):
y_upper.append(np.max((y_right[i+1], y_right[i])))
y_lower.append(intersection[1])
dx = (intersection[0]-x_left[i])
x_new.append(intersection[0]+dx)
y_upper.append(y_right[i])
y_lower.append(y_right[i+1])
#
s = s_new
y_upper.append(y_left[-1])
y_lower.append(y_left[-1])
x_new.append(x_right[-1])
#
return x_new, y_lower, y_upper
I'm attaching a figure that shows the results from fill_betweenx() to show the additional area I want to shade.