【问题标题】:why does my colorbar have lines in it?为什么我的颜色条中有线条?
【发布时间】:2013-02-06 20:11:48
【问题描述】:

编辑:因为这似乎是一个受欢迎的帖子,所以这里的解决方案似乎对我很有效。谢谢@gazzar 和@mfra。

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

有谁知道为什么我的颜色条中似乎有线条?或者更确切地说,为什么颜色过渡不平滑?显然,我正在使用底图,但这无关紧要,因为它是 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 示例而不会出现此问题。

【问题讨论】:

  • 您是否尝试过将图形保存为不同的格式?如果是,您是否总是遇到此问题?
  • 我只看到这个是 alpha 的结果,你确定它和 alpha=1.0 一样吗?
  • 是的,它发生在 png 上,但我没有解决这个问题。是的,我看到 alpha = 1.0 和 SVG。
  • 嗯.. 下面列出的选项似乎都没有为我解决问题。当我将无花果另存为 PDF 时,我的颜色栏仍然有白线。
  • 在最新编辑中作为解决方案给出的两行不应一起使用。一个或另一个就足够了。

标签: python matplotlib matplotlib-basemap


【解决方案1】:

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

“已知某些矢量图形查看器(svg 和 pdf)会在颜色条的段之间呈现白色间隙。这是由于查看器中的错误而不是 matplotlib。作为一种解决方法,可以使用重叠段来呈现颜色条:

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

但是,这在其他情况下会产生负面影响。特别是对于半透明图像(alpha

【讨论】:

  • 谢谢。这似乎确实是阅读 #1188 和附加的(恢复的)PR 的问题。同样有趣的是,SVG 在 Firefox 和 Chrome 中的呈现方式确实不同,这是我没有想到的。
  • 看起来 alpha
  • 这确实是查看器中的一个错误,但使用次优方式渲染颜色条也是如此。整个图形应使用平滑阴影而不是 256 个小矩形绘制为一个整体。 PDF 和 SVG 格式都支持任意颜色的线性平滑着色。
【解决方案2】:

看起来您的绘图使用了一些透明 (alpha) 值。我遇到了同样的问题(半透明的情节,但希望颜色条是实心的),而 questionanswer 为我解决了这个问题!供参考:

cbar.set_alpha(1)
cbar.draw_all()

【讨论】:

  • 这改变了我在颜色栏中的颜色图!为什么??什么鬼:D
【解决方案3】:

我尝试了其他 cmets 上的两种设置,即

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

不幸的是,它们都不适合我。

所以我尝试了一种完全不同的方法,这是一个巨大的 hack,但至少可以完成工作。当您将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')

在这里,我基于winter 创建了一个新的颜色图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")

现在将其与您在没有此技巧的情况下获得的图像进行比较:

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

这会产生一个颜色条没有线条但仍保持透明度的图像。虽然它仍然是一个巨大的 hack,但至少我们不必再忍受这些行了!

【讨论】:

  • 我应用了最后一个技巧(不带 alpha 的绘图,绘制颜色条,带 alpha 的绘图),因为我必须通过 imshow 运行图像,第二个透明地覆盖在第一个上,第二个有彩条。因此遇到了透明条纹问题。
【解决方案4】:

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

cbar.solids.set_rasterized(True) 

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

【讨论】:

  • 两年后回到这里。这确实有很大帮助。
  • 优秀。看起来更好,而且 svg 输出也更小!
【解决方案5】:

试试:

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,您是在告诉它绘制这些线。

【讨论】:

  • drawedges 确实为我绘制了边缘,但将它们绘制为黑色!不是特别有帮助。 mfra 的解决方案对我来说没有优势。 (matplotlib v1.3.1)
【解决方案6】:

由于没有其他建议对我有用,我最终从颜色条实例中删除了 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)

必须先绘制一次颜色条,然后才能访问面部颜色。

【讨论】:

    【解决方案7】:

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

    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)
    

    【讨论】:

      猜你喜欢
      • 2020-05-25
      • 2012-09-04
      • 1970-01-01
      • 1970-01-01
      • 2015-01-03
      • 1970-01-01
      • 2021-09-29
      • 2014-10-27
      • 1970-01-01
      相关资源
      最近更新 更多