pcolormesh:使用 ec='face' 时的伪像/重叠点

问题描述 投票:0回答:1

我正在使用 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')

python matplotlib cartopy
1个回答
0
投票

与绘图大小/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)

© www.soinside.com 2019 - 2024. All rights reserved.