我正在使用 pcolormesh 和 cartopy 绘制地图。当我不使用选项
edgecolor
或将其设置为 None 时,结果与预期一致。但是当我使用 ec='face'
时,我会得到非常奇怪的人工制品和/或重叠点 - 取决于所选的输出格式。
我尝试过 snap
和 antialiased
但不幸的是这些没有帮助。
当我放大交互式图时,它看起来并没有那么糟糕,但我的输出文件(pdf 或 png)看起来一团糟。
如何激活边缘颜色而不出现这种奇怪的行为?
MWE如下。使用 蟒蛇 3.10.12, matplotlib 3.5.1, 卡托比 0.22.0.
import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
proj1 = ccrs.PlateCarree()
proj2 = ccrs.LambertAzimuthalEqualArea()
fig = plt.figure(figsize=(16,8), layout='constrained')
# generate coordinates
xx = np.linspace(-10,30,300)
yy = np.linspace( 35,75,300)
xxx,yyy = np.meshgrid(xx,yy)
rng = np.random.default_rng(6666)
# create artificial data
zzz = xxx + yyy
noise = rng.normal(0,np.nanmax(zzz)*0.1,zzz.shape)
zzz += noise
# create some gaps in data
zdim = zzz.size
idx = rng.choice(range(zdim), size=zdim//3)
zshape = zzz.shape
zz = zzz.flatten()
zz[idx] = np.nan
zzz = zz.reshape(zshape)
ax = fig.add_subplot(1,2,1, projection=proj2)
ax.add_feature(cfeature.BORDERS, lw=0.5, ec='k')
ax.add_feature(cfeature.COASTLINE, lw=0.5, ec='k')
# looks ok
ax.pcolormesh(xxx, yyy, zzz,
transform=proj1)
ax = fig.add_subplot(1,2,2, projection=proj2)
ax.add_feature(cfeature.BORDERS, lw=0.5, ec='k')
ax.add_feature(cfeature.COASTLINE, lw=0.5, ec='k')
# looks not ok
ax.pcolormesh(xxx, yyy, zzz,
#snap=True,
#antialiased=True,
ec='face', # this seems to have a problem here
transform=proj1)
plt.show()
#plt.savefig('plot_test.pdf')
与绘图大小/dpi 相比,数据的分辨率相当高。再加上
edge
实际上是在边缘绘制的,而不是局限于四边形的内部,导致边缘覆盖相邻数据。
增加图形尺寸/dpi 可能会有所帮助,或者减小边缘的默认线宽以更适合面/四边形的尺寸。线宽等属性以点为单位指定,与图形相关,因此与数据的大小/分辨率无关。
将线条颜色设置为红色也许可以更好地强调该行为。下图是网格缩小到 100x100,并放大了一点。
import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
# generate coordinates
xx = np.linspace(-10,30, 100)
yy = np.linspace( 35,75, 100)
xxx,yyy = np.meshgrid(xx,yy)
rng = np.random.default_rng(6666)
# create artificial data
zzz = xxx + yyy
noise = rng.normal(0,np.nanmax(zzz)*0.1,zzz.shape)
zzz += noise
# create some gaps in data
zdim = zzz.size
idx = rng.choice(range(zdim), size=zdim//3)
zshape = zzz.shape
zz = zzz.flatten()
zz[idx] = np.nan
zzz = zz.reshape(zshape)
data_proj = ccrs.PlateCarree()
map_proj = ccrs.LambertAzimuthalEqualArea()
fig, axs = plt.subplot_mosaic(
"ABC;DEF", figsize=(12,7), layout='constrained',
subplot_kw={"projection": map_proj}, facecolor="w",
)
axs["A"].set_title("No edge")
axs["A"].pcolormesh(xxx, yyy, zzz, transform=data_proj)
axs["B"].set_title("edge=face, default lw")
axs["B"].pcolormesh(xxx, yyy, zzz, transform=data_proj, ec='face')
axs["C"].set_title("edge=face, small lw")
axs["C"].pcolormesh(xxx, yyy, zzz, transform=data_proj, ec='face', lw=0.1)
axs["D"].set_title("No edge")
axs["D"].pcolormesh(xxx, yyy, zzz, transform=data_proj)
axs["E"].set_title("edge=r, default lw")
axs["E"].pcolormesh(xxx, yyy, zzz, transform=data_proj, ec='r')
axs["F"].set_title("edge=r, small lw")
axs["F"].pcolormesh(xxx, yyy, zzz, transform=data_proj, ec='r', lw=0.1)
for ax in axs.values():
ax.add_feature(cfeature.BORDERS, lw=0.5, ec='k', alpha=.5)
ax.add_feature(cfeature.COASTLINE, lw=0.5, ec='k', alpha=.5)
ax.set_extent((0, 30, 60, 76), crs=data_proj)