Matplotlib:用透明颜色填充轮廓图

wea*_*rog 9 python matplotlib

有人知道 - 在Matplotlib中 - 如何使用半透明颜色生成外观漂亮的填充轮廓图?如果contourf()传递具有半透明颜色的色彩图,则会在填充区域之间产生小间隙:

区域之间的差距很小

根据文档,这不是一个错误(" contourf()[...]不绘制多边形边缘").要绘制边缘,建议"通过调用添加线条轮廓contour()".但是,由于边缘变得太不透明,这看起来并不好看:

边缘太不透明

你可以玩一下这个linewidth论点contour(),但这没什么用.有任何想法吗?

这是重现问题的代码(我使用面向对象的API,但结果是相同的pyplot):

import matplotlib
import numpy as np
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg

# generate some data
shape = (100, 100)
x_rng = np.linspace(-1, 1, shape[1])
y_rng = np.linspace(-1, 1, shape[0])
x, y = np.meshgrid(x_rng, y_rng)
z = np.sqrt(x**2 + y**2)

# create figure
width_inch, height_inch = 5, 5  # results in 500x500px with dpi=100
fig = Figure()
fig.set_size_inches((width_inch, height_inch))
FigureCanvasAgg(fig)
ax = fig.add_axes([0., 0., 1., 1.])
ax.set_axis_off()

# define some colors with alpha < 1
alpha = 0.9
colors = [
    (0.1, 0.1, 0.5, alpha),  # dark blue
    (0.0, 0.7, 0.3, alpha),  # green
    (0.9, 0.2, 0.7, alpha),  # pink
    (0.0, 0.0, 0.0, alpha),  # black
    (0.1, 0.7, 0.7, alpha),  # light blue
]
cmap = matplotlib.colors.ListedColormap(colors)
levels = np.array(np.linspace(0, z.max(), len(colors)))
norm = matplotlib.colors.BoundaryNorm(levels, ncolors=cmap.N)

# contourf plot produces small gaps between filled areas
cnt = ax.contourf(x, y, z, levels, cmap=cmap, norm=norm,
                  antialiased=True, linecolor='none')

# this fills the gaps, but it makes them too opaque
# ax.contour(x, y, z, levels, cmap=cmap, norm=norm,
#            antialiased=True)

# the same is true for this trick:
# for c in cnt.collections:
#     c.set_edgecolor("face")

filename = "/tmp/contourf.png"
fig.savefig(filename, dpi=100, transparent=True, format="png")
Run Code Online (Sandbox Code Playgroud)

PS:SVG后端的情节相同.

PPS:pcolormesh()有类似的问题:

ax.pcolormesh(x, y, z, cmap=cmap, norm=norm,
              edgecolor="face", antialiased=True)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

dec*_*lts 1

我不知道这是否能解决您的问题,因为“好看”有点主观,但是在放大到该级别时获得没有任何抗锯齿问题或锯齿状边缘的图像的唯一方法是是使用矢量格式,如 SVG、EPS 等(正如您所指出的)。

SVG(可缩放矢量图形)

在此输入图像描述

如果关闭抗锯齿功能,则可以消除边缘模糊和“不透明”,但在高缩放级别下,圆圈会出现锯齿状边缘外观。您可以尝试将 dpi 增加到 300dpi,然后另存为 tiff:

Tiff、300dpi、抗锯齿=False

在此输入图像描述

抗锯齿会沿着圆形边界混合图像,因此混合透明的粉色和绿色会产生看起来更暗的颜色,这可能会给人看起来更不透明的印象,即使透明度理论上是相同的。

通过注释/注释代码的以下部分,我得到了看起来不同的结果,但结果太主观,无法说哪个更好看:

设置轮廓但不设置边缘颜色:

ax.contour(x, y, z, levels, cmap=cmap, norm=norm,
            antialiased=True)

# the same is true for this trick:
# for c in cnt.collections:
#     c.set_edgecolor("face")
Run Code Online (Sandbox Code Playgroud)

不设置轮廓,但设置边缘颜色:

# ax.contour(x, y, z, levels, cmap=cmap, norm=norm,
#            antialiased=True)

# the same is true for this trick:
 for c in cnt.collections:
     c.set_edgecolor("face")
Run Code Online (Sandbox Code Playgroud)

但它们是否好看取决于解释。我发现的另一件事是我的图像查看器内置了自己的抗锯齿功能,因此您在尝试进行比较时可能需要将其关闭。