为什么我的colorbar中有线条?

时间:2013-02-21 13:22:29

标签: python matplotlib matplotlib-basemap

编辑:由于这似乎是一个热门帖子,这里的解决方案似乎对我有用。谢谢@gazzar和@mfra。

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

有谁知道为什么我的colorbar看起来像是哪条线?或者更确切地说为什么颜色过渡不平滑?显然,我正在使用底图,但这并不重要,因为它是引擎盖AFAICT下的所有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")

我试过没有和没有alpha,结果是一样的。也许是因为我的color_values数组不够好?我可以在某处设置映射到颜色条的基础值吗?我不知道怎么样,我在其他地方看不到这个问题。也就是说,我可以在没有这个问题的情况下复制matplotlib show_colorbars示例。

Bad Colorbar Example

7 个答案:

答案 0 :(得分:27)

如果你创建了矢量图形,你试过这个(取自http://matplotlib.org/api/pyplot_api.html?highlight=colorbar#matplotlib.pyplot.colorbar):

“众所周知,某些矢量图形查看器(svg和pdf)会在颜色条的各个部分之间产生白色间隙。这是由于观察者中的错误而不是matplotlib。作为一种解决方法,可以使用重叠的部分呈现颜色条: / p>

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

然而,这在其他情况下会产生负面影响。特别是半透明图像(alpha< 1)和colorbar扩展名,默认情况下不启用,请参阅(问题#1188)。“

答案 1 :(得分:8)

我通常更喜欢通过添加以下行来使用Eric Firing的建议here来栅格化颜色条内容以避免此问题。

cbar.solids.set_rasterized(True) 

对于具有透明度的图像,此解决方法可能会失败,但对于大多数正常情况,它会产生所需的结果。

答案 2 :(得分:7)

看起来你的情节使用了一些透明(alpha)值。我有同样的问题(半透明图,但希望颜色条是实心的),这questionanswer为我修复了它!供参考:

cbar.set_alpha(1)
cbar.draw_all()

答案 3 :(得分:7)

我尝试了其他评论中给出的两种设置,即

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

并且不幸的是,我都没有工作。

所以我尝试了一种完全不同的方法,这是一个巨大的黑客,但至少完成工作。当您将alpha传递给imshow时,它会设置一个alpha值,用于与其他图片混合。由于功率较高的原因(正如@mfra所提到的),这就产生了我们如此鄙视的白线。显然,关键是将alpha值传递给imshow。但是,我们仍然需要以某种方式创建颜色条。

因此,作为一种解决方法,我们可以在向imshow提供色彩映射之前自己进行alpha混合。例如,让我们使用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')

在这里,我基于my_cmap_rgb创建一个新的色彩映射winter,然后编辑非alpha通道(0,1和2)以自行进行alpha混合。然后,我可以简单地使用这个新的色彩图来绘制我的身材。

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

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")

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")

这会产生一个图像,其颜色条没有线条但仍保留透明度。虽然它仍然是一个巨大的黑客,至少我们不再需要忍受这些线!

No lines and transparency

答案 4 :(得分:1)

尝试:

cbar = mymap.colorbar(sc, drawedges=False, location="bottom")

现在网上有很好的记录(我能找到),但是

*drawedges*   [ False | True ] If true, draw lines at color
              boundaries.

(从matplotlib/lib/matplotlib/colorbar.py拉出来)我认为通过将drawedges设置为True,您可以告诉它绘制这些线条。

答案 5 :(得分:0)

以下可能是另一种解决方案,即使它不优雅。

In [1]: children = cbar.ax.get_children()
In [2]: children
Out[2]:
[<matplotlib.collections.QuadMesh at 0x21783c41b70>,
 <matplotlib.collections.LineCollection at 0x21783bfdc18>,
 <matplotlib.patches.Polygon at 0x21783ba0588>,
 <matplotlib.patches.Polygon at 0x21783beef98>,
 <matplotlib.spines.Spine at 0x21783b77c88>,
 <matplotlib.spines.Spine at 0x21783b77470>,
 <matplotlib.spines.Spine at 0x21783b70c88>,
 <matplotlib.spines.Spine at 0x21783b70860>,
 <matplotlib.axis.XAxis at 0x21783b6ac50>,
 <matplotlib.axis.YAxis at 0x21783ba60f0>,
 <matplotlib.text.Text at 0x21783bc2198>,
 <matplotlib.text.Text at 0x21783bc2320>,
 <matplotlib.text.Text at 0x21783bc22b0>,
 <matplotlib.patches.Rectangle at 0x21783bc2358>]
In [3]: obj = children[1]  # Get the LineCollection object
In [4]: obj.set_linewidth(0)

答案 6 :(得分:0)

由于没有其他建议对我有用,我最终从彩条实例中移除了alpha通道:

from matplotlib.colors import to_rgb

lut = colorbar.solids.get_facecolor()
bg_color = to_rgb('white')
lut[:, :3] *= lut[:, 3:]
lut[:, :3] += (1 - lut[:, 3:]) * bg_color
lut[:, 3] = 1.
colorbar.solids.set_facecolor(lut)

在能够访问面部颜色之前,必须绘制一次颜色条。