我有一个函数f,我想在两个轮廓之间填充颜色。左图中一个轮廓显示为蓝色。该轮廓由两条不相交的曲线组成。中间图中另一个轮廓显示为绿色,由一条曲线组成。右侧的最终图像中同时显示了两个轮廓。
f
ax.contour()当一条轮廓由两条不相交的曲线组成时,如何在这两条轮廓(使用生成)之间填充?
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()
但问题是这需要相当长的时间并且最终的产品不是特别整洁。
使用contourf:
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()
输出:
结合contour和contourf以获得更佳的显示效果:
contour
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=['-'])
使用该nchunk参数可以实现更好的抗锯齿效果,但仍然会产生一些瑕疵:
nchunk
contours = ax.contourf(x, y, z, levels=[-0.02, 0.02], antialiased=True, nchunk=20, colors='forestgreen')