Edit: Since this seems to be a popular post, here's the solution that seems to be working well for me. Thanks @gazzar and @mfra.
编辑:由于这似乎是一个受欢迎的帖子,这里的解决方案似乎对我有用。谢谢@gazzar和@mfra。
cbar.solids.set_rasterized(True)
cbar.solids.set_edgecolor("face")
Does anyone know why my colorbar has what appear to be lines in it? Or rather why is the color transition not smooth? I'm using basemap, obviously, but that shouldn't matter since it's all matplotlib calls under the hood AFAICT. I create the map doing something like
有谁知道为什么我的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")
I tried without and without alpha and the result was the same. Maybe it is because my color_values array is not fine enough? Can I set the underlying values that are mapped to the colorbar somewhere? I don't see how, and I don't see this problem elsewhere. Ie., I can replicate the matplotlib show_colorbars example without this problem.
我试过没有和没有alpha,结果是一样的。也许是因为我的color_values数组不够好?我可以在某处设置映射到颜色条的基础值吗?我不知道怎么样,我也没有在其他地方看到这个问题。也就是说,我可以复制matplotlib show_colorbars示例而不会出现此问题。
7 个解决方案
#1
25
In case you create vector graphics, have you tried this (taken from http://matplotlib.org/api/pyplot_api.html?highlight=colorbar#matplotlib.pyplot.colorbar):
如果你创建矢量图形,你试过这个(取自http://matplotlib.org/api/pyplot_api.html?highlight=colorbar#matplotlib.pyplot.colorbar):
"It is known that some vector graphics viewer (svg and pdf) renders white gaps between segments of the colorbar. This is due to bugs in the viewers not matplotlib. As a workaround the colorbar can be rendered with overlapping segments:
“众所周知,一些矢量图形查看器(svg和pdf)在颜色条的各个部分之间呈现白色间隙。这是由于观察者中的错误而不是matplotlib。作为一种解决方法,可以使用重叠的部分呈现颜色条:
cbar = colorbar()
cbar.solids.set_edgecolor("face")
draw()
However this has negative consequences in other circumstances. Particularly with semi transparent images (alpha < 1) and colorbar extensions and is not enabled by default see (issue #1188)."
然而,这在其他情况下会产生负面影响。特别是对于半透明图像(alpha <1)和colorbar扩展名,默认情况下不启用,请参阅(问题#1188)。“
#2
8
I generally prefer to rasterize the colorbar contents to avoid this issue using Eric Firing's advice here by adding the following line.
我通常更喜欢光栅化colorbar内容,以通过添加以下行使用Eric Firing的建议来避免此问题。
cbar.solids.set_rasterized(True)
This workaround supposedly fails for images with transparency, but for most normal cases it produces the desired result.
对于具有透明度的图像,这种解决方法可能会失败,但对于大多数正常情况,它会产生所需的结果。
#3
5
It looks like your plot uses some transparent (alpha) values. I was having this same problem (semi-transparent plot, but wanted the color bar to be solid), and this question and answer fixed it for me! For reference:
看起来你的情节使用了一些透明(alpha)值。我有同样的问题(半透明的情节,但希望颜色条是坚实的),这个问题和答案为我修复了它!以供参考:
cbar.set_alpha(1)
cbar.draw_all()
#4
5
I tried both settings given on the other comments, namely
我尝试了其他评论中给出的两种设置,即
cbar.solids.set_rasterized(True)
cbar.solids.set_edgecolor("face")
and unfortunately neither worked for me.
不幸的是,两者都没有为我工作。
So I tried a completely different approach which is a huge hack, but at least gets the job done. When you pass alpha
to imshow
it sets an alpha value that will be used to blending with other images. Due to reasons of higher power (as @mfra has mentioned) this creates the white lines we so despise. Clearly the key then is to not pass an alpha value to imshow
. However, we still need to somehow create the colorbar.
所以我尝试了一种完全不同的方法,这是一个巨大的黑客,但至少完成工作。将alpha传递给imshow时,它会设置一个alpha值,用于与其他图像混合。由于功率较高的原因(正如@mfra所提到的),这就产生了我们如此鄙视的白线。显然,关键是不要将alpha值传递给imshow。但是,我们仍然需要以某种方式创建颜色条。
Thus as a workaround we can do the alpha blending ourselves before ever giving colormaps to imshow
. As an example, let's use the winter
colormap:
因此,作为一种解决方法,我们可以自己进行alpha混合,然后再将colormaps用于imshow。举个例子,让我们使用冬季色彩图:
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')
Here I create a new colormap, my_cmap_rgb
, based on winter
and then edit the non-alpha channels (0, 1 and 2) to do the alpha blending myself. I can then simply use this new colormap to plot my figure.
在这里,我基于冬天创建一个新的色图my_cmap_rgb,然后编辑非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")
Now compare it with the image you'd obtain without this trick:
现在将它与你没有这个技巧获得的图像进行比较:
f, ax = plt.subplots()
cim = ax.imshow(zz, cmap='winter', alpha=0.5)
cbar = plt.colorbar(cim)
ax.set_title("Lines and transparency")
Clearly the problem is solved if you require no transparency. On the other hand, if you do require transparency, there is one more workaround. You have to first plot an image without transparency to obtain the colorbar, and then plot one with transparency, but whose colorbar won't be used.
显然,如果您不需要透明度,问题就解决了。另一方面,如果您确实需要透明度,还有一个解决方法。您必须首先绘制没有透明度的图像以获得颜色条,然后绘制一个具有透明度的图像,但不使用其颜色条。
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")
This results in an image whose colorbar has no lines and yet still retains the transparency. While it remains a massive hack, at least we don't have to put up with these lines anymore!
这导致图像的颜色条没有线条但仍保留透明度。虽然它仍然是一个巨大的黑客,至少我们不必忍受这些线路了!
#5
1
Try:
尝试:
cbar = mymap.colorbar(sc, drawedges=False, location="bottom")
It is now well documented on the web (that I could find), but
它现在在网上有很好的记录(我可以找到),但是
*drawedges* [ False | True ] If true, draw lines at color
boundaries.
(pulled from matplotlib/lib/matplotlib/colorbar.py
) I think by setting drawedges
to True
you are telling it to draw those lines.
(从matplotlib / lib / matplotlib / colorbar.py中提取)我认为通过将drawedges设置为True,您可以告诉它绘制这些线条。
#6
0
The following can be another solution even if it is not elegant.
即使不优雅,以下可以是另一种解决方案。
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)
#7
0
Since none of the other suggestions worked for me I ended up removing the alpha channel from the colorbar instance:
由于没有其他建议对我有用,我最终从colorbar实例中删除了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)
The colorbar had to be drawn once before being able to access the face colors.
在能够访问面部颜色之前,必须绘制一次颜色条。
#1
25
In case you create vector graphics, have you tried this (taken from http://matplotlib.org/api/pyplot_api.html?highlight=colorbar#matplotlib.pyplot.colorbar):
如果你创建矢量图形,你试过这个(取自http://matplotlib.org/api/pyplot_api.html?highlight=colorbar#matplotlib.pyplot.colorbar):
"It is known that some vector graphics viewer (svg and pdf) renders white gaps between segments of the colorbar. This is due to bugs in the viewers not matplotlib. As a workaround the colorbar can be rendered with overlapping segments:
“众所周知,一些矢量图形查看器(svg和pdf)在颜色条的各个部分之间呈现白色间隙。这是由于观察者中的错误而不是matplotlib。作为一种解决方法,可以使用重叠的部分呈现颜色条:
cbar = colorbar()
cbar.solids.set_edgecolor("face")
draw()
However this has negative consequences in other circumstances. Particularly with semi transparent images (alpha < 1) and colorbar extensions and is not enabled by default see (issue #1188)."
然而,这在其他情况下会产生负面影响。特别是对于半透明图像(alpha <1)和colorbar扩展名,默认情况下不启用,请参阅(问题#1188)。“
#2
8
I generally prefer to rasterize the colorbar contents to avoid this issue using Eric Firing's advice here by adding the following line.
我通常更喜欢光栅化colorbar内容,以通过添加以下行使用Eric Firing的建议来避免此问题。
cbar.solids.set_rasterized(True)
This workaround supposedly fails for images with transparency, but for most normal cases it produces the desired result.
对于具有透明度的图像,这种解决方法可能会失败,但对于大多数正常情况,它会产生所需的结果。
#3
5
It looks like your plot uses some transparent (alpha) values. I was having this same problem (semi-transparent plot, but wanted the color bar to be solid), and this question and answer fixed it for me! For reference:
看起来你的情节使用了一些透明(alpha)值。我有同样的问题(半透明的情节,但希望颜色条是坚实的),这个问题和答案为我修复了它!以供参考:
cbar.set_alpha(1)
cbar.draw_all()
#4
5
I tried both settings given on the other comments, namely
我尝试了其他评论中给出的两种设置,即
cbar.solids.set_rasterized(True)
cbar.solids.set_edgecolor("face")
and unfortunately neither worked for me.
不幸的是,两者都没有为我工作。
So I tried a completely different approach which is a huge hack, but at least gets the job done. When you pass alpha
to imshow
it sets an alpha value that will be used to blending with other images. Due to reasons of higher power (as @mfra has mentioned) this creates the white lines we so despise. Clearly the key then is to not pass an alpha value to imshow
. However, we still need to somehow create the colorbar.
所以我尝试了一种完全不同的方法,这是一个巨大的黑客,但至少完成工作。将alpha传递给imshow时,它会设置一个alpha值,用于与其他图像混合。由于功率较高的原因(正如@mfra所提到的),这就产生了我们如此鄙视的白线。显然,关键是不要将alpha值传递给imshow。但是,我们仍然需要以某种方式创建颜色条。
Thus as a workaround we can do the alpha blending ourselves before ever giving colormaps to imshow
. As an example, let's use the winter
colormap:
因此,作为一种解决方法,我们可以自己进行alpha混合,然后再将colormaps用于imshow。举个例子,让我们使用冬季色彩图:
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')
Here I create a new colormap, my_cmap_rgb
, based on winter
and then edit the non-alpha channels (0, 1 and 2) to do the alpha blending myself. I can then simply use this new colormap to plot my figure.
在这里,我基于冬天创建一个新的色图my_cmap_rgb,然后编辑非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")
Now compare it with the image you'd obtain without this trick:
现在将它与你没有这个技巧获得的图像进行比较:
f, ax = plt.subplots()
cim = ax.imshow(zz, cmap='winter', alpha=0.5)
cbar = plt.colorbar(cim)
ax.set_title("Lines and transparency")
Clearly the problem is solved if you require no transparency. On the other hand, if you do require transparency, there is one more workaround. You have to first plot an image without transparency to obtain the colorbar, and then plot one with transparency, but whose colorbar won't be used.
显然,如果您不需要透明度,问题就解决了。另一方面,如果您确实需要透明度,还有一个解决方法。您必须首先绘制没有透明度的图像以获得颜色条,然后绘制一个具有透明度的图像,但不使用其颜色条。
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")
This results in an image whose colorbar has no lines and yet still retains the transparency. While it remains a massive hack, at least we don't have to put up with these lines anymore!
这导致图像的颜色条没有线条但仍保留透明度。虽然它仍然是一个巨大的黑客,至少我们不必忍受这些线路了!
#5
1
Try:
尝试:
cbar = mymap.colorbar(sc, drawedges=False, location="bottom")
It is now well documented on the web (that I could find), but
它现在在网上有很好的记录(我可以找到),但是
*drawedges* [ False | True ] If true, draw lines at color
boundaries.
(pulled from matplotlib/lib/matplotlib/colorbar.py
) I think by setting drawedges
to True
you are telling it to draw those lines.
(从matplotlib / lib / matplotlib / colorbar.py中提取)我认为通过将drawedges设置为True,您可以告诉它绘制这些线条。
#6
0
The following can be another solution even if it is not elegant.
即使不优雅,以下可以是另一种解决方案。
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)
#7
0
Since none of the other suggestions worked for me I ended up removing the alpha channel from the colorbar instance:
由于没有其他建议对我有用,我最终从colorbar实例中删除了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)
The colorbar had to be drawn once before being able to access the face colors.
在能够访问面部颜色之前,必须绘制一次颜色条。