【问题标题】:How does parameters 'c' and 'cmap' behave in a matplotlib scatter plot?参数“c”和“cmap”在 matplotlib 散点图中如何表现?
【发布时间】:2019-02-06 01:54:14
【问题描述】:

对于pyplot.scatter(x,y,s,c....)函数,

matplotlib 文档指出:

c : 颜色、序列或颜色序列,可选,默认:'b' 标记颜色。可能的值:

单一颜色格式字符串。一系列颜色规格 长度 n。使用 cmap 将 n 个数字的序列映射到颜色 和规范。一个二维数组,其中行是 RGB 或 RGBA。请注意,c 不应是单个数字 RGB 或 RGBA 序列,因为那是 与要进行颜色映射的值数组无法区分。如果你 要为所有点指定相同的 RGB 或 RGBA 值,请使用 2-D 单行数组。

但是我不明白如何根据需要更改数据点的颜色

我有这段代码:

import matplotlib.pyplot as plt
import numpy as np
import sklearn
import sklearn.datasets
import sklearn.linear_model
import matplotlib


%matplotlib inline
matplotlib.rcParams['figure.figsize'] = (13.0, 9.0)

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.55)
print(y)
plt.scatter(X[:,0], X[:,1], c=y)#, cmap=plt.cm.Spectral)

the output plot

如果我愿意,如何更改颜色以假设黑色和绿色数据点?或者是其他东西 ?还请解释一下 cmap 的作用。

为什么每次我使用 plt.cm.Spectral 时我的图都是洋红色和蓝色的?

【问题讨论】:

  • 这取决于您发送给c=yy 中存在的值。
  • 此处的值将仅为 1 和 0 。我可以操纵它来制作其他东西,比如 4 和 5 。但是,它仍然是相同颜色的相同图像

标签: python-3.x matplotlib plot colors scikit-learn


【解决方案1】:

关于如何为散点着色基本上有两种选择。

1。外部映射

您可以在外部将值映射到颜色,并将这些颜色的列表/数组提供给scatterc 参数。

z = np.array([1,0,1,0,1])
colors = np.array(["black", "green"])
plt.scatter(x,y, c=colors[z])

2。内部映射

除了显式颜色之外,还可以提供一个值列表/数组,这些值应该根据规范化和颜色映射映射到颜色。

  • colormap 是一个可调用对象,它将 0.1. 之间的浮点值作为输入并返回 RGB 颜色。
  • 标准化是一种可调用对象,它可以根据一些先前设置的限制将任何数字作为输入并输出另一个数字。 Normalize 的常见情况将提供vminvmax 之间的值到0.1. 之间范围的线性映射。

因此,从某些数据中获取颜色的自然方法是将两者链接起来,

cmap = plt.cm.Spectral
norm = plt.Normalize(vmin=4, vmax=5)
z = np.array([4,4,5,4,5])
plt.scatter(x,y, c = cmap(norm(z)))

这里4 的值将通过归一化映射到05 的值将映射到1,这样颜色图就提供了最外层的两种颜色。

如果将数值数组提供给c,则此过程在scatter 内部发生。

scatter 创建一个PathCollection,它是ScalarMappable 的子类。 ScalarMappable 由颜色图、规范化和值数组组成。因此,以上内容通过

plt.scatter(x,y, c=z, norm=norm, cmap=cmap)

如果要将最小和最大数据用作规范化的限制,您可以忽略该参数。

plt.scatter(x,y, c=z, cmap=cmap)

这就是问题中的输出始终为紫色和黄色点的原因,与提供给c的值无关。

回到将01 的数组映射到黑色和绿色的要求,您现在可以查看colormaps provided by matplotlib 并查找包含黑色和绿色的颜色图。例如。 nipy_spectral 颜色图

这里黑色位于颜色图的开头,绿色位于中间某处,例如0.5。因此需要将vmin 设置为0,并将vmax 设置为vmax*0.5 = 1(将1 的值映射为绿色),即vmax = 1./0.5 == 2

import matplotlib.pyplot as plt
import numpy as np
x,y = np.random.rand(2,6)
z = np.array([0,0,1,1,0,1])

plt.scatter(x,y, c = z, 
            norm = plt.Normalize(vmin=0, vmax=2),
            cmap = "nipy_spectral")

plt.show()

由于可能并不总是存在具有所需颜色的颜色图,而且从现有颜色图中获取颜色位置可能不是直接的,因此另一种方法是专门为所需目的创建新的颜色图。

在这里,我们可以简单地创建一个包含黑色和绿色两种颜色的颜色图。

matplotlib.colors.ListedColormap(["black", "green"])

我们在这里不需要任何规范化,因为我们只有两个值,因此可以依赖自动规范化。

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
x,y = np.random.rand(2,6)
z = np.array([0,0,1,1,0,1])

plt.scatter(x,y, c = z, cmap = mcolors.ListedColormap(["black", "green"]))

plt.show()

【讨论】:

    【解决方案2】:

    首先,根据y中的值设置颜色,你可以这样做:

    color = ['red' if i==0  else 'green' for i in y]
    plt.scatter(X[:,0], X[:,1], c=color)
    

    现在谈谈scatter()cmap

    ColorMaps 用于根据浮点值提供颜色。见this documentation for reference on colormaps

    对于 0 到 1 之间的值,从这些颜色图中选择一种颜色。

    例如:

    plt.cm.Spectral(0.0)
    # (0.6196078431372549, 0.00392156862745098, 0.25882352941176473, 1.0) #<== magenta
    
    plt.cm.Spectral(1.0)
    # (0.3686274509803922, 0.30980392156862746, 0.6352941176470588, 1.0) #<== blue
    
    plt.cm.Spectral(1)
    # (0.6280661284121491, 0.013302575932333718, 0.26082276047673975, 1.0)
    

    请注意,上面代码中 1.0 和 1 的结果是不同的,因为 __call__() here 的文档中提到的 int 和 float 的处理方式不同:

    对于浮点数,X 应该在区间 [0.0, 1.0] 中以返回 RGBA 值 X*100 沿颜色图线的百分比。

    对于整数,X 应该在区间[0, Colormap.N) 到 从索引为 X 的颜色图中返回 RGBA 值索引

    请查看此答案以获得有关颜色图的更多更好解释:-

    在您的 y 中,您有 0 和 1,因此使用上面代码中显示的 RGBA 值(它们代表 Spectral 颜色图的两端)。

    下面是plt.scatter() 中的ccmap 参数如何相互交互。

     _______________________________________________________________________
    |No | type of x, y |  c type  | values in c |       result              |
    |___|______________|__________|_____________|___________________________|
    |1  |   single     |  scalar  |   numbers   | cmap(0.0), no matter      |
    |   |    point     |          |             |  what the value in c      |
    |___|______________|__________|_____________|___________________________|
    |2  |   array of   |  array   |   numbers   | normalize the values in c,|                
    |   |    points    |          |             | cmap(normalized val in c) |
    |___|______________|__________|_____________|___________________________|
    |3  | scalar or    | scalar or| RGBA Values,|  no use of cmap,          |
    |   |  array       |  array   |Color Strings|  use colors from c        |
    |___|______________|__________|_____________|___________________________|
    

    现在,一旦最终确定了实际颜色,然后循环遍历x, y 中每个点的颜色。如果 x, y 的大小等于或小于 c 中颜色的大小,那么你得到了完美的映射,否则会再次使用旧的颜色。

    这里有一个例子来说明这一点:

    # Case 1 from above table
    
    # All three points get the same color = plt.cm.Spectral(0)
    plt.scatter(x=0.0, y=0.2, c=0, cmap=plt.cm.Spectral)
    plt.scatter(x=0.0, y=0.3, c=1, cmap=plt.cm.Spectral)
    plt.scatter(x=0.0, y=0.4, c=1.0, cmap=plt.cm.Spectral)
    
    # Case 2 from above table
    
    # The values in c are normalized 
    # highest value in c gets plt.cm.Spectral(1.0)
    # lowest value in c gets plt.cm.Spectral(0.0)
    # Others in between as per normalizing
    # Size of arrays in x, y, and c must match here, else error is thrown
    plt.scatter([0.1, 0.1, 0.1, 0.1, 0.1], [0.2, 0.3, 0.4, 0.5, 0.6], 
                c=[1, 2, 3, 4, 5], cmap=plt.cm.Spectral)
    
    
    # Case 3 from above table => No use of cmap here,
    #  blue is assigned to the point
    plt.scatter(x=0.2, y=0.3, c='b')
    
    # You can also provide rgba tuple
    plt.scatter(x=0.2, y=0.4, c=plt.cm.Spectral(0.0))
    
    # Since a single point is present, the first color (green) is given
    plt.scatter(x=0.2, y=0.5, c=['g', 'r'])
    
    # Same color 'cyan' is assigned to all values
    plt.scatter([0.3, 0.3, 0.3, 0.3, 0.3], [0.2, 0.3, 0.4, 0.5, 0.6], 
                c='c')
    
    # Colors are cycled through points
    # 4th point will get again first color
    plt.scatter([0.4, 0.4, 0.4, 0.4, 0.4], [0.2, 0.3, 0.4, 0.5, 0.6], 
                c=['m', 'y', 'k'])
    
    # Same way for rgba values
    # Third point will get first color again
    plt.scatter([0.5, 0.5, 0.5, 0.5, 0.5], [0.2, 0.3, 0.4, 0.5, 0.6], 
                c=[plt.cm.Spectral(0.0), plt.cm.Spectral(1.0)])
    

    输出:

    通过代码中的 cmets 和点的位置以及颜色来彻底理解。

    您也可以将案例3代码中的参数c替换为color,结果还是一样。

    【讨论】:

    • 这是部分正确的。即使 OP 的 y 数组在区间 (0,1) 包含不同的值,该图仍将显示相同的最外层颜色。这是由于使用中的归一化,它总是归一化到 (0,1) 区间。
    • @ImportanceOfBeingErnest 我已经编辑了答案。请看看这是否正确。
    • 看起来没有什么问题。关于用整数调用颜色图的部分是正确的,但可能有点令人困惑,因为在没有规范化的情况下,颜色图在内部永远不会被调用,并且总是会返回浮点值,即Spectral(norm(1)) 将给出正确的 rgb 值,即使@987654348 @ 是一个整数。
    • @ImportanceOfBeingErnest Spectral(norm(1)) 的值不等于Spectral(0.0) 吗?
    • ...当然取决于规范。但是假设norm=plt.Normalize(0,1),然后Spectral(norm(1)) == Spectral(1.0)
    猜你喜欢
    • 1970-01-01
    • 2015-12-11
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2017-03-01
    相关资源
    最近更新 更多