首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在matplotlib中突出显示多条曲线中最低的一条曲线(包络)

如何在matplotlib中突出显示多条曲线中最低的一条曲线(包络)
EN

Stack Overflow用户
提问于 2021-11-12 00:58:13
回答 1查看 48关注 0票数 2

假设我有多个由Python函数表示的数学函数f1f2f3。我想把它们一起画在0,1的域上。

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
import math

def f1(x):
    return 4*x**3 + 9*x**2 + x + 4
def f2(x):
    return math.sqrt(x) / (1.01 - x)
def f3(x):
    return 30 * math.cos(6 * x)

x = np.arange(0.0, 1.01, 0.01)
for f in [f1, f2, f3]:
    vecf = np.vectorize(f)
    y = vecf(x)
    plt.plot(x, y)
plt.xlim([0, 1])
plt.xlabel(r'$x$')
plt.ylabel(r'$f(x)$')
plt.show()

但是,我希望使用alpha = 1高亮显示所有最低的曲线分段(即封套),同时使用alpha = 0.5高亮显示曲线的其他部分。我想保留每条曲线的颜色。预期的绘图如下所示:

有人能建议如何在matplotlib中实现这一点吗?

EN

Stack Overflow用户

回答已采纳

发布于 2021-11-12 01:14:23

我尝试了我在评论中建议的方法(“只画出所有曲线,然后计算一个实际上是其他曲线组合的最小值的系列,并将其绘制出来,但使用100%透明的线条颜色,并将其上方的整个区域着色为部分不透明的白色。”)我认为它非常接近你所需要的:

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
import math

def f1(x):
    return 4*x**3 + 9*x**2 + x + 4
def f2(x):
    return math.sqrt(x) / (1.01 - x)
def f3(x):
    return 30 * math.cos(6 * x)

x = np.arange(0.0, 1.01, 0.01)
# initialise min_y to all infinite, there is probably a more efficient way to do this
min_y = np.inf * np.ones(x.shape)
for f in [f1, f2, f3]:
    vecf = np.vectorize(f)
    y = vecf(x)
    # zorder=0 to push curves below plane 
    plt.plot(x, y, zorder=0)
    # compute min_y as we go
    min_y = np.minimum(y, min_y)

# what you need, although the +1 is a bit arbitrary
# you may want to add some amount relative to the plt.ylim()
plt.fill_between(x, min_y+1, plt.ylim()[1], color='white', alpha=.5)

plt.xlim([0, 1])
plt.xlabel(r'$x$')
plt.ylabel(r'$f(x)$')
plt.show()

结果:

从你的例子来看,你可能想要一个更像.7的alpha。

偷偷摸摸的后续问题,也是为了让台词变得丰满:

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
import math

def f1(x):
    return 4*x**3 + 9*x**2 + x + 4

def f2(x):
    return math.sqrt(x) / (1.01 - x)

def f3(x):
    return 30 * math.cos(6 * x)

x = np.arange(0.0, 1.01, 0.01)
# initialise min_y to all infinite, there is probably a more efficient way to do this
min_y = np.inf * np.ones(x.shape)
plotted = []
for f in [f1, f2, f3]:
    vecf = np.vectorize(f)
    y = vecf(x)
    # zorder=0 to push curves below plane
    p = plt.plot(x, y, zorder=0)
    # compute min_y as we go
    min_y = np.minimum(y, min_y)
    # keep the plotted data, to reuse when plotting fat lines
    plotted.append((y, p[0].get_color()))

for y, c in plotted:
    plt.plot(x, np.ma.masked_where(y > min_y, y), color=c, zorder=1, linewidth=3)

# what you need, although the +1 is a bit arbitrary - you may want to add some amount relative to the plt.ylim()
plt.fill_between(x, min_y+1, plt.ylim()[1], color='white', alpha=.7)

plt.xlim([0, 1])
plt.xlabel(r'$x$')
plt.ylabel(r'$f(x)$')
plt.show()

结果:

票数 3
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69936741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档