小能豆

Matplotlib 填充轮廓线之间的区域,其中一条轮廓线由两条不相交的曲线组成

py

我有一个函数f,我想在两个轮廓之间填充颜色。左图中一个轮廓显示为蓝色。该轮廓由两条不相交的曲线组成。中间图中另一个轮廓显示为绿色,由一条曲线组成。右侧的最终图像中同时显示了两个轮廓。

1.png

ax.contour()当一条轮廓由两条不相交的曲线组成时,如何在这两条轮廓(使用生成)之间填充?

最小工作示例

以下代码创建感兴趣的函数,生成值网格,然后绘制并存储轮廓。

import numpy as np
from numpy import apply_along_axis, meshgrid, arange, vstack
import matplotlib.pyplot as plt

# Function whose level-sets we are interested in
f = lambda x: x[1]**2 + 3*(x[0]**2)*(x[0]**2 - 1)
f_broadcasted = lambda x: apply_along_axis(f, 1, x)

# Generate grid of (x, y, z) values to plot contour
xlims, ylims = [-2, 2], [-2, 2]
x, y = meshgrid(arange(*xlims, 0.005), arange(*ylims, 0.005))
xys = vstack((x.flatten(), y.flatten())).T
z = f_broadcasted(xys).reshape(x.shape)

# Plot contours
fig, ax = plt.subplots()
contours = ax.contour(x, y, z, levels=[-0.02, 0.02], colors=['forestgreen', 'royalblue'])
plt.show()

输出结果与上图最右边的图基本类似。我尝试使用

ax.fill_between(*contours[1][0].T, contours[0][1])

但问题是它们的尺寸不同。

基本上,我想要的输出可以通过绘制许多轮廓来实现(以一种丑陋的方式)

fig, ax = plt.subplots()
contours = ax.contour(x, y, z, levels=np.linspace(-0.02, 0.02, num=1000), colors='black', linestyles='-')
plt.show()

但问题是这需要相当长的时间并且最终的产品不是特别整洁。
2.png


阅读 29

收藏
2024-12-03

共1个答案

小能豆

使用contourf

import numpy as np
from numpy import apply_along_axis, meshgrid, arange, vstack
import matplotlib.pyplot as plt

# Function whose level-sets we are interested in
f = lambda x: x[1]**2 + 3*(x[0]**2)*(x[0]**2 - 1)
f_broadcasted = lambda x: apply_along_axis(f, 1, x)

# Generate grid of (x, y, z) values to plot contour
xlims, ylims = [-2, 2], [-2, 2]
x, y = meshgrid(arange(*xlims, 0.005), arange(*ylims, 0.005))
xys = vstack((x.flatten(), y.flatten())).T
z = f_broadcasted(xys).reshape(x.shape)

# Plot contours
fig, ax = plt.subplots()
contours = ax.contourf(x, y, z, levels=[-0.02, 0.02], colors='forestgreen')
plt.show()

输出:

1.png

结合contourcontourf以获得更佳的显示效果:

contours = ax.contourf(x, y, z, levels=[-0.02, 0.02], colors='forestgreen')
ax.contour(x, y, z, levels=[-0.02, 0.02],
           colors=['forestgreen', 'royalblue'], linestyles=['-'])

输出:

2.png

使用该nchunk参数可以实现更好的抗锯齿效果,但仍然会产生一些瑕疵:

contours = ax.contourf(x, y, z, levels=[-0.02, 0.02],
                       antialiased=True, nchunk=20,
                       colors='forestgreen')

3.png

2024-12-03