简体   繁体   中英

Matplotlib fill_between invert?

I am trying to fill the regions below two intersecting lines and above both lines, using matplotlib. I can fill between both lines, but haven't found a simple way to invert the region obtained previously. The only workaround I have is to created some extra functions (a low one and a min one for the bottom, and the equivalents for the top), which is a bit cumbersome and requires manual inputs (see below). Any better solutions?

插图

import numpy as np
import matplotlib.pyplot as plt

# Doesn't work
def f1(x): return 32.0 * x + 2.0
def f2(x): return -55.0 * x
xRng=[-1, 1]
plt.plot(xRng, [f1(x) for x in xRng], 'b-')
plt.plot(xRng, [f2(x) for x in xRng], 'r-')
plt.fill_between(xRng, [f1(x) for x in xRng], [f2(x) for x in xRng], color='g') # Would like the fill inverted
plt.title('Not good'); plt.show()

# Works, but clumsy
def fLo(x): return -100
def fHi(x): return 100
def fMin(x): return min(f1(x), f2(x))
def fMax(x): return max(f1(x), f2(x))
xRng=np.linspace(-1, 1, 100)
plt.plot(xRng, [f1(x) for x in xRng], 'b-')
plt.plot(xRng, [f2(x) for x in xRng], 'r-')
plt.fill_between(xRng, [fMin(x) for x in xRng], [fLo(x) for x in xRng], color='g')
plt.fill_between(xRng, [fMax(x) for x in xRng], [fHi(x) for x in xRng], color='g')
plt.title('Complicated'); plt.show()

EDIT: swapping BG and FG colors as suggested by @Mad Physicist will work if basic case, but not if there are several such areas to overlay

It appears that fill_between does not do well with infinite values (eg Fill area under curve in matlibplot python on log scale ). However, if you're only trying to plot those specific lines, you could just invert the colors of the plot:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-1, 1, 100)
y1 = 32.0 * x + 2.0
y2 = -55.0 * x

fig, ax = plt.subplots()
ax.set_facecolor('g')
ax.plot(x, y1, 'b-')
ax.plot(x, y2, 'r-')
ax.fill_between(x, y1, y2, color='w')
ax.set_xlim(x.min(), x.max())
plt.show()

在此处输入图像描述

This is very hacky and won't work well with interactive plots, but it will display the plot you want, hopefully fairly painlessly.

在此处输入图像描述

A slightly better approach might be to set the background of only the region covered by x to a green patch:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-1, 1, 100)
y1 = 32.0 * x + 2.0
y2 = -55.0 * x

fig, ax = plt.subplots()
ax.plot(x, y1, 'b-')
ax.plot(x, y2, 'r-')
ax.axvspan(x.min(), x.max(), color='g')
ax.fill_between(x, y1, y2, color='w')
ax.set_xlim(x.min(), x.max())
plt.show()

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM