为什么我的颜色条里有线条?

51 投票
7 回答
12600 浏览
提问于 2025-04-17 16:37

编辑: 由于这个帖子似乎很受欢迎,这里是我找到的一个有效的解决方案。感谢@gazzar和@mfra。

cbar.solids.set_rasterized(True)
cbar.solids.set_edgecolor("face")

有没有人知道为什么我的颜色条里有看起来像是线条的东西?或者说,为什么颜色的过渡不够平滑?我显然在使用basemap,但这应该没关系,因为底层都是matplotlib的调用。我的地图是通过类似下面的方式创建的:

grays = plt.cm.get_cmap("Grays")
sc = mymap.scatter(xpoints, ypoints, s=sizes, c=color_values, cmap=grays, alpha=.75,
                   marker="o", zorder=10, vmin=0, vmax=1)
cbar = mymap.colorbar(sc, drawedges=True, location="bottom")

我尝试过有和没有透明度,结果都是一样的。可能是因为我的color_values数组不够细腻吧?我可以在某个地方设置映射到颜色条的基础值吗?我看不出来,而且在其他地方没有看到这个问题。也就是说,我可以在没有这个问题的情况下复现matplotlib的show_colorbars示例。

颜色条问题示例

7 个回答

10

我试过其他评论里提到的两种设置,

cbar.solids.set_rasterized(True)
cbar.solids.set_edgecolor("face")

但是很遗憾,这两种方法对我都没用。

于是我尝试了一种完全不同的方法,虽然这个方法有点“黑科技”,但至少能解决问题。当你把 alpha 传给 imshow 时,它会设置一个透明度值,用来和其他图像混合。由于某些原因(正如 @mfra 提到的),这会导致我们讨厌的白线出现。所以关键是要 不要 把透明度值传给 imshow。不过,我们还是需要想办法创建颜色条。

因此,作为一个变通方法,我们可以在给 imshow 之前自己处理透明度混合。举个例子,我们可以使用 winter 这个颜色映射:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

xx, yy = np.meshgrid(np.linspace(-1, 1, 100), np.linspace(-1, 1, 100))
zz = xx**2 + yy**2

my_cmap_rgb = plt.get_cmap('winter')(np.arange(256))
alpha = 0.5

for i in range(3): # Do not include the last column!
    my_cmap_rgb[:,i] = (1 - alpha) + alpha*my_cmap_rgb[:,i]
my_cmap = mpl.colors.ListedColormap(my_cmap_rgb, name='my_cmap')

在这里,我基于 winter 创建了一个新的颜色映射 my_cmap_rgb,然后编辑了非透明度通道(0、1 和 2),自己进行透明度混合。接着,我可以简单地用这个新的颜色映射来绘制我的图。

f, ax = plt.subplots()
cim = ax.imshow(zz, cmap=my_cmap)
cbar = plt.colorbar(cim)
ax.set_title("No lines and no transparency")

没有线条和透明度

现在把它和没有这个技巧得到的图像进行比较:

f, ax = plt.subplots()
cim = ax.imshow(zz, cmap='winter', alpha=0.5)
cbar = plt.colorbar(cim)
ax.set_title("Lines and transparency")

有线条和透明度

显然,如果你不需要透明度,这个问题就解决了。另一方面,如果你确实需要透明度,还有一个变通方法。你需要先绘制一幅没有透明度的图像,以获得颜色条,然后再绘制一幅有透明度的图像,但不使用它的颜色条。

f, ax = plt.subplots()
cim = ax.imshow(zz, cmap=my_cmap)
cbar = plt.colorbar(cim)
plt.cla()  # Clears axis
ax.plot(50,50, 'ko')
ax.imshow(zz, cmap='winter', alpha=0.5)
ax.set_title("No lines and transparency")

这样就得到了一个颜色条没有线条,但仍然保留透明度的图像。虽然这仍然是个大黑科技,但至少我们不再需要忍受这些线条了!

没有线条和透明度

11

看起来你的图表使用了一些透明的(alpha)值。我之前也遇到过这个问题(图表半透明,但我希望颜色条是实心的),这个问题和这个回答帮我解决了!供你参考:

cbar.set_alpha(1)
cbar.draw_all()
32

如果你在制作矢量图形,是否试过这个(摘自 http://matplotlib.org/api/pyplot_api.html?highlight=colorbar#matplotlib.pyplot.colorbar):

“有些矢量图形查看器(比如svg和pdf)在显示颜色条时,会在颜色条的不同部分之间出现白色的间隙。这是因为查看器本身的bug,而不是matplotlib的问题。为了绕过这个问题,可以让颜色条的部分重叠显示:

cbar = colorbar()
cbar.solids.set_edgecolor("face")
draw()

不过,这样做在其他情况下会有负面影响。特别是当使用半透明的图像(透明度小于1)和颜色条的扩展时,这种重叠显示并不是默认开启的,具体可以参考(问题 #1188)。”

撰写回答