【发布时间】:2020-08-19 05:34:14
【问题描述】:
我有以下代码:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-np.pi/2, np.pi/2, 30)
y = np.linspace(-np.pi/2, np.pi/2, 30)
x,y = np.meshgrid(x,y)
z = np.sin(x**2+y**2)[:-1,:-1]
fig,ax = plt.subplots()
ax.pcolormesh(x,y,z)
现在假设我想突出显示某些网格框的边缘:
highlight = (z > 0.9)
我可以使用轮廓函数,但这会导致“平滑”轮廓。我只想在网格框的边缘之后突出显示区域的边缘。
我最接近的是添加这样的内容:
highlight = np.ma.masked_less(highlight, 1)
ax.pcolormesh(x, y, highlight, facecolor = 'None', edgecolors = 'w')
这很接近,但我真正想要的是仅突出显示“甜甜圈”的外边缘和内边缘。
所以本质上我正在寻找一些轮廓和 pcolormesh 函数的混合 - 一些遵循某个值的轮廓,但在“步骤”中遵循网格箱而不是连接点对点的东西。这有意义吗?
旁注:在 pcolormesh 参数中,我有 edgecolors = 'w',但边缘仍然是蓝色的。那里发生了什么?
编辑:
JohanC 使用 add_iso_line() 的初始答案适用于提出的问题。但是,我使用的实际数据是一个非常不规则的 x,y 网格,无法转换为一维(add_iso_line() 需要。
我正在使用从极坐标 (rho, phi) 转换为笛卡尔 (x,y) 的数据。 JohanC 提出的 2D 解决方案似乎不适用于以下情况:
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage
def pol2cart(rho, phi):
x = rho * np.cos(phi)
y = rho * np.sin(phi)
return(x, y)
phi = np.linspace(0,2*np.pi,30)
rho = np.linspace(0,2,30)
pp, rr = np.meshgrid(phi,rho)
xx,yy = pol2cart(rr, pp)
z = np.sin(xx**2 + yy**2)
scale = 5
zz = ndimage.zoom(z, scale, order=0)
fig,ax = plt.subplots()
ax.pcolormesh(xx,yy,z[:-1, :-1])
xlim = ax.get_xlim()
ylim = ax.get_ylim()
xmin, xmax = xx.min(), xx.max()
ymin, ymax = yy.min(), yy.max()
ax.contour(np.linspace(xmin,xmax, zz.shape[1]) + (xmax-xmin)/z.shape[1]/2,
np.linspace(ymin,ymax, zz.shape[0]) + (ymax-ymin)/z.shape[0]/2,
np.where(zz < 0.9, 0, 1), levels=[0.5], colors='red')
ax.set_xlim(*xlim)
ax.set_ylim(*ylim)
【问题讨论】:
-
是的,这个问题很明确也很有用
-
z[z>0.9] = 0 或 z[z>0.9] = 1 更改值,使它们不同。请注意,pyplot 会自动分配颜色图。您可能想要使用灰度颜色图。或者您可能只想使用 cv2.imshow() 以灰度查看它。然后您可以转换为 3 个通道并使强调红色 z1=cv2.merge([z,z,z]) 然后 z1[z>0.9]=(255,255,255)
标签: python matplotlib contour