Search code examples
pythonmatplotliblinear-programming

Fixing filling for feasible region


I'm trying to correct the filling for a feasible region using Python's matplotlib

These are the inequalities:

x = np.linspace(0, 2000, 1000)
y1 = (3600 - 3*x) / 5
y2 = (1600 - x) / 2
y3 = (48000 - 50*x) / 20

I only care about the feasible region but I can't get the constraints right

fig, ax = plt.subplots()
ax.plot(x, y1, label='3x+5y<=3600')
ax.plot(x, y2, label='x+2y<=1600')
ax.plot(x, y3, label='50x+20y<=48000')
ax.fill_between(x, 0, y3, where=(y1<= (3600-3*x)/5) & (y2<= (1600-x)/2) & (y3<= (48000-50*x)/20), alpha=0.2)

# plot the vertices
for vertex in vertices:
    ax.plot(vertex[0], vertex[1], 'ro')

plt.xlim(xmin=0)
plt.ylim(ymin=0)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Feasible Region')
plt.legend()
plt.show()

enter image description here

As you can notice the feasible region is not filled correctly, although the logic seems fine to me.
How to fix the fill_between parameters so it would fill it correctly?


Solution

  • First, let me explain why your code doesn't work. If you read the fill_between documentation carefully you'll see that the where argument is for limiting the left-right extent of the fill-between. So, if you did where=(x<=500), the line would stop at x=500.

    In this case, because your lines are all bounding the top of the feasible region, you can use np.minimum.reduce to get the element-wise minimum of all the lines giving you the top of the feasible region. You can then use the where argument to limit the region to where the lines are all above 0 (without it, the shading would extend further down to the right, though you won't see it with the specified limits).

    top = np.minimum.reduce([y1, y2, y3])
    ax.fill_between(x, top, 0, alpha=0.2, where=(top>0))