参数'c'和'cmap'在matplotlib散点图中的表现如何?

问题描述 投票:4回答:2

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

matplotlib文档指出:

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

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

但是我不明白我如何根据自己的意愿改变数据点的颜色。

我有这段代码:

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时我的阴影都是洋红色和蓝色?

python-3.x matplotlib plot colors scikit-learn
2个回答
7
投票

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

1. External mapping

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

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

2. Internal mapping

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

  • 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的值将通过归一化映射到0,并且5的值被映射到1,使得colormap提供两种最外面的颜色。

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

一个scatter创造了一个PathCollection,其子类ScalarMappableScalarMappable由colormap,normalization和值数组组成。因此,上述内容是通过

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色彩图

enter image description here

这里的黑色位于色彩图的开头,绿色位于中间的某个位置,比如在0.5。因此,需要将vmin设置为0,并将vmax设置为vmax*0.5 = 11将值映射为绿色),即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()

enter image description here

由于可能并不总是存在具有所需颜色的色彩图,并且因为从现有色彩图获得色彩位置可能不是直接的,所以替代方案是专门为所需目的创建新的色彩图。

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

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

enter image description here


1
投票

首先,要根据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

enter image description here

对于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的结果在上面的代码中是不同的,因为int和float的处理方式不同,如__call__() here文档中所述:

对于浮点数,X应该在区间[0.0, 1.0]中,以沿着Colormap行返回RGBA值X*100百分比。

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

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

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

现在这里是c中的cmapplt.scatter()参数如何相互作用。

 _______________________________________________________________________
|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中的颜色大小,那么您将获得完美的映射,否则将再次使用olders颜色。

这是一个例子来说明这一点:

# 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)])

输出:

enter image description here

通过代码中的注释和点的位置以及颜色来彻底了解。

您也可以在案例3的代码中用c替换param color,结果仍然相同。

© www.soinside.com 2019 - 2024. All rights reserved.