Masking out a region using matplotlib

Viewed 84

hope you are doing well,

So, I am currently working in some plot that looks like this:

enter image description here

I need the red region to be (white!, and therefore covering) over everything that is plotted before that lines of code. This way I would mask out all the middle of the arrows. The problem is that the portion I am filling in with red (I would like it to be white) is kind of transparent, even though I am setting alpha=1.0.

The code below:

import numpy as np
from scipy.stats import norm
import matplotlib as mpl
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
from matplotlib import rc, font_manager
import matplotlib.colors as colors

rc('text', usetex=True)
plt.rc('font', family='serif')
#plt.rcParams.update({'font.size': 18})


xminlim = 0.0
xmaxlim = 1.0
yminlim = 0.0
ymaxlim = 1.0

fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(8,15))

# first row
row_y_1  = 0.8
col_x_11 = 0.1
col_x_12 = 0.175
col_x_13 = 0.25
col_x_14 = 0.325
col_x_15 = 0.4
col_x_16 = 0.475
col_x_17 = 0.55
col_x_18 = 0.625
col_x_19 = 0.7
col_x_1N = 0.9

row1_vect= [col_x_11,col_x_12,col_x_13,col_x_14,col_x_15,col_x_16,col_x_17,col_x_18,col_x_19,col_x_1N]
for posx in row1_vect:
    plt.scatter(posx, row_y_1, marker= 'o',facecolors='none', s = 300, color='black')

plt.scatter(0.75, row_y_1,color='black',marker = 'o',s = 20)
plt.scatter(0.80, row_y_1,color='black',marker = 'o',s = 20)
plt.scatter(0.85, row_y_1,color='black',marker = 'o',s = 20)


# second row
row_y_2  = 0.7
col_x_21 = 0.175
col_x_22 = 0.250
col_x_23 = 0.325
col_x_24 = 0.400
col_x_25 = 0.475
col_x_26 = 0.550
col_x_27 = 0.625
col_x_2N = 0.850

row2_vect= [col_x_21,col_x_22,col_x_23,col_x_24,col_x_25,col_x_26,col_x_27,col_x_2N]

delta = 0.013
for origin in row1_vect:
    for destiny in row2_vect:
        ax.annotate("",xy=(destiny,row_y_2+delta), xycoords='data',xytext=(origin, row_y_1-delta), textcoords='data',
            arrowprops=dict(arrowstyle="->",connectionstyle="arc3"),)

for posx in row2_vect:
    plt.scatter(posx, row_y_2, marker= 'o',facecolors="none", s = 300, color='black')     

plt.scatter(0.68125, row_y_2,color='black',marker = 'o', s = 20)
plt.scatter(0.7375 , row_y_2,color='black',marker = 'o', s = 20)
plt.scatter(0.79375, row_y_2,color='black',marker = 'o', s = 20)

# last-1 row
row_y_last_1  = 0.3
col_x_l1 = 0.25
col_x_l2 = 0.33
col_x_l3 = 0.41
col_x_l4 = 0.50
col_x_l5 = 0.58
col_x_l6 = 0.66
col_x_l7 = 0.75

row1_vect= [col_x_21,col_x_22,col_x_23,col_x_24,col_x_25,col_x_26,col_x_27,col_x_2N]
row2_vect= [col_x_l1,col_x_l2,col_x_l3,col_x_l4,col_x_l5,col_x_l6,col_x_l7]


delta = 0.013
for origin in row1_vect:
    for destiny in row2_vect:
        ax.annotate("",xy=(destiny,row_y_last_1+delta), xycoords='data',xytext=(origin, row_y_2-delta), textcoords='data',
            arrowprops=dict(arrowstyle="->",connectionstyle="arc3"),)

for posx in row2_vect:
    plt.scatter(posx, row_y_last_1, marker= 'o',facecolors="none", s = 300, color='black')


# last row
row_y_last  = 0.2
col_x_21 = 0.3
col_x_22 = 0.38
col_x_23 = 0.46
col_x_24 = 0.54
col_x_25 = 0.62
col_x_26 = 0.7


row1_vect= [col_x_l1,col_x_l2,col_x_l3,col_x_l4,col_x_l5,col_x_l6,col_x_l7]
row2_vect= [col_x_21,col_x_22,col_x_23,col_x_24,col_x_25,col_x_26]

delta = 0.013
for origin in row1_vect:
    for destiny in row2_vect:
        ax.annotate("",xy=(destiny,row_y_last+delta), xycoords='data',xytext=(origin, row_y_last_1-delta), textcoords='data',
            arrowprops=dict(arrowstyle="->",connectionstyle="arc3"),)

for xpos in row2_vect:
    plt.scatter(xpos, row_y_last, marker= 'o',facecolors="none", s = 300, color='black')            


# START THE MASKING. DOESNT WORK
def consfun1(x):
    return np.full(x.shape, 0.4)

def consfun2(x):
    return np.full(x.shape, 0.6)

N  = np.linspace(0,1,600)
A1 = consfun1(N)
A2 = consfun2(N)
  
plt.plot(N, A1, color="white",lw = 3)
plt.plot(N, A2, color="white",lw = 3)
plt.fill_between(N, A2, A1, 
                  color = 'r', 
                  alpha = 1.0)

# vertical points ABOVE MASKING
x_coord  = 0.5
y_coord1 = 0.55
y_coord2 = 0.50
y_coord3 = 0.44
plt.scatter(x_coord, y_coord1,color='black',marker = 'o', s = 20)
plt.scatter(x_coord, y_coord2,color='black',marker = 'o', s = 20)
plt.scatter(x_coord, y_coord3,color='black',marker = 'o', s = 20)


left,right = plt.xlim()
plt.xlim(left  = xminlim) 
plt.xlim(right = xmaxlim) 
bottom, top = plt.ylim()
plt.ylim(bottom = yminlim)
plt.ylim(top    = ymaxlim)

fname = "maskedfigure"
plt.savefig(fname,
    bbox_inches='tight',
    facecolor   = 'w',
    edgecolor   = 'w',
    orientation = 'portrait',
    papertype   = None,
    transparent = False,
    pad_inches  = 0.1,
    frameon     = None,
    metadata    = None)

plt.show()

why is it the filled in area not being plotted over all the other plots?. How can I achieve the desired output? Thanks in advance and hope you are doing well!

1 Answers

The fill_between is drawn on a layer below the plot lines unless you change its z order as below:

plt.fill_between(N, A2, A1,
                 color='r',
                 zorder = 10)

Of course you can change its color to white but I have shown it in red to match your example: enter image description here

Related