对于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)
如果我愿意,我怎样才能改变颜色以设想黑色和绿色数据点?或者是其他东西 ?另外请解释一下cmap究竟是做什么的。
为什么每次使用plt.cm.Spectral时我的阴影都是洋红色和蓝色?
关于如何着色散点的基本上有两种选择。
您可以在外部将值映射到颜色,并将这些颜色的列表/数组提供给scatter
的c
参数。
z = np.array([1,0,1,0,1])
colors = np.array(["black", "green"])
plt.scatter(x,y, c=colors[z])
除了显式颜色外,还可以提供值列表/数组,这些值应根据规范化和色彩映射映射到颜色。
colormap
是一个可调用的,它将0.
和1.
之间的浮点值作为输入并返回RGB颜色。Normalize
的通常情况将提供vmin
和vmax
之间的值的线性映射到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
,其子类ScalarMappable
。 ScalarMappable
由colormap,normalization和值数组组成。因此,上述内容是通过
plt.scatter(x,y, c=z, norm=norm, cmap=cmap)
如果要将最小和最大数据用作规范化的限制,则可以保留该参数。
plt.scatter(x,y, c=z, cmap=cmap)
这就是问题中输出总是紫色和黄色点的原因,与c
提供的值无关。
回到将0
和1
数组映射到黑色和绿色的要求,您现在可以查看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()
首先,要根据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的结果在上面的代码中是不同的,因为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
中的cmap
和plt.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)])
输出:
通过代码中的注释和点的位置以及颜色来彻底了解。
您也可以在案例3的代码中用c
替换param color
,结果仍然相同。