【问题标题】:NaN values as special color in pyplot scatter plotNaN 值作为 pyplot 散点图中的特殊颜色
【发布时间】:2019-09-21 18:40:22
【问题描述】:

我有一个 (x,y) 散点图,其中每个点都与一种颜色相关联。然而,有些点没有有效的颜色,并被分配为 NaN。我想包括这些点,但以颜色图未包含的颜色显示它们。

示例代码如下:

import numpy as np
import matplotlib.colors as mcol
import matplotlib.pyplot as plt

numPoints = 20
nanFrequency = 3
xVec = np.arange(numPoints, dtype=float)
yVec = xVec
colorVec = np.linspace(0,1,numPoints)
colorVec[range(0, numPoints, nanFrequency)] = np.nan

colormap = mcol.LinearSegmentedColormap.from_list("Blue-Red-Colormap", ["b", "r"])

plt.scatter(xVec, yVec, c=colorVec, cmap=colormap)

和相应的输出:

由于其颜色值无效,因此不会显示每三个点。根据我的代码,我希望这些点显示为黄色。为什么这不起作用?

请注意,有一个related post concerning imshow(),上面的代码就是从中获得灵感的。那里提出的解决方案似乎对我不起作用。

非常感谢。

【问题讨论】:

    标签: python-3.x matplotlib


    【解决方案1】:

    NaN 值未绘制的原因是 matplotlib 的散点图当前在将它们提供给颜色图之前将它们过滤掉。

    要显示NaN 条目,您可以手动为它们分配一个具有特殊含义的虚拟值。例如,因为您的列表在[0, 1] 范围内,您可以定义任何值> 1 获得特殊颜色。为此,您必须固定颜色轴的范围,并为超出此范围的条目指定颜色(在这种情况下高于最大值)。

    基本上你会使用:

    cax = ax.scatter(...)
    cax.cmap.set_over('y') # assigns yellow to any entry >1
    cax.set_clim(0, 1)     # fixes the range of 'normal' colors to (0, 1)
    

    你的例子:

    import numpy as np
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    numPoints = 20
    nanFrequency = 3
    xVec = np.arange(numPoints, dtype=float)
    yVec = xVec
    colorVec = np.linspace(0,1,numPoints)
    colorVec[range(0, numPoints, nanFrequency)] = np.NaN
    
    cmap = mpl.colors.LinearSegmentedColormap.from_list("Blue-Red-Colormap", ["b", "r"], numPoints)
    
    # ---
    
    fig, axes = plt.subplots(nrows=2, figsize=(8, 2*6))
    
    # ---
    
    ax = axes[0]
    
    ax.scatter(xVec, yVec, c=colorVec, cmap=cmap)
    
    ax.set_xlim([0, 20])
    ax.set_ylim([0, 20])
    
    # ---
    
    ax = axes[1]
    
    colorVec[np.isnan(colorVec)] = 2.0
    
    cax = ax.scatter(xVec, yVec, c=colorVec, cmap=cmap)
    cax.cmap.set_over('y')
    cax.set_clim(0, 1)
    
    ax.set_xlim([0, 20])
    ax.set_ylim([0, 20])
    
    # ---
    
    plt.show()
    

    这会产生两个子图:顶部对应于您所拥有的,底部使用虚拟值并将黄色分配给它:

    【讨论】:

      【解决方案2】:

      当然,您需要为颜色图设置所需的黄色,colormap.set_bad("yellow")

      然后,这是 matplotlib (#4354) 中长期存在的错误,幸运的是现在已修复 (#12422)。

      因此,从 matplotlib 3.1 开始,您可以使用 plotnonfinite=True 参数在散点图中包含屏蔽点或无效点。

      import numpy as np
      import matplotlib.colors as mcol
      import matplotlib.pyplot as plt
      
      numPoints = 20
      nanFrequency = 3
      xVec = np.arange(numPoints, dtype=float)
      yVec = xVec
      colorVec = np.linspace(0,1,numPoints)
      colorVec[range(0, numPoints, nanFrequency)] = np.nan
      
      colormap = mcol.LinearSegmentedColormap.from_list("Blue-Red-Colormap", ["b", "r"])
      colormap.set_bad("yellow")
      
      plt.scatter(xVec, yVec, c=colorVec, cmap=colormap, plotnonfinite=True)
      
      plt.show()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-13
        • 1970-01-01
        • 1970-01-01
        • 2021-07-06
        • 1970-01-01
        • 2018-12-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多