有人知道 - 在Matplotlib中 - 如何使用半透明颜色生成外观漂亮的填充轮廓图?如果contourf()
传递的是具有半透明颜色的色彩映射,则会在填充区域之间产生小间隙:
根据docs,这不是一个错误(" contourf()
[...]不会绘制多边形边缘")。要绘制边缘,建议通过调用contour()
"来添加线轮廓。但是,当边缘变得太不透明时,这看起来并不好看:
您可以使用linewidth
的{{1}}参数,但这并没有多大帮助。有什么想法吗?
这里是重现问题的代码(我使用面向对象的API,但结果与contour()
相同):
pyplot
PS:SVG后端的情节相同。
PPS: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")
有类似的问题:
pcolormesh()
答案 0 :(得分:1)
我不知道这是否能解决你的问题,因为'好看'在某种程度上是主观的,但是当放大到没有任何抗锯齿问题或锯齿状边缘的图像的唯一方法该级别将使用矢量格式,如SVG,EPS等(正如您所指出的)。
SVG(可缩放矢量图形)
如果关闭抗锯齿功能,可以消除边缘模糊和“不透明度”,但在高变焦级别时,圆形会出现锯齿状边缘。你可以尝试增加dpi来说300dpi,并保存为tiff:
Tiff,300dpi,antialiasing = False
抗锯齿将沿着圆形边界混合您的图像,因此混合透明的粉红色和绿色会产生更暗的颜色,这可能会给人一种看起来更不透明的印象,即使透明度在概念上是相同的
我通过评论代码的以下部分得到了不同的结果,但结果太主观了,不能说哪个更好看:
设置轮廓但不设置edgecolor:
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")
不要设置轮廓,而是设置边缘颜色:
# 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")
但是要解释它们是否看起来很好。我发现的另一件事是我的图像查看器内置了自己的抗锯齿功能,因此您可能希望在尝试进行比较时将其关闭。