Python 散点图:如何使用与颜色循环具有相同颜色的颜色图

Python scatterplot: how to use a colormap that has the same colors as the colorcycle

我正在尝试为散点图中的聚类着色,我使用两种不同的方法进行了处理。

在第一个中,我迭代地绘制每个集群,在第二个中,我一次绘制所有数据并根据它们的标签 [0, 1, 2, 3 ,4] 为集群着色。

我对在 example1example3 中得到的结果很满意,但我不明白为什么在根据标签为聚类着色而不是迭代绘制每个聚类时颜色会发生如此显着的变化群集。

此外,为什么第二个集群(尽管始终标记为“1”)在示例 1 和示例 3 中具有不同的颜色?

import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight') #irrelevant here, but coherent with the examples=)

fig, ax = plt.subplots(figsize=(6,4))
for clust in range(kmeans.n_clusters):
    ax.scatter(X[kmeans.labels_==clust],Y[kmeans.labels_==clust])
    ax.set_title("example1")`

plt.figure(figsize = (6, 4))
plt.scatter(X,Y,c=kmeans.labels_.astype(float))
plt.title("example2")

(我知道我可以为第二种方法显式定义颜色图,但我找不到任何可以重现示例 1 中结果的颜色图)

这是一个最小的工作示例

import matplotlib.pyplot as plt
import pandas as pd
plt.style.use('fivethirtyeight') #irrelevant here, but coherent with the examples=)
X=pd.Series([1, 2, 3, 4, 5, 11, 12, 13, 14, 15])
Y=pd.Series([1,1,1,1,1,2,2,2,2,2])
clusters=pd.Series([0,0,0,0,0,1,1,1,1,1])


fig, ax = plt.subplots(figsize=(6,4))
for clust in range(2):
ax.scatter(X[clusters==clust],Y[clusters==clust])
ax.set_title("example3")

plt.figure(figsize = (6, 4))
plt.scatter(X,Y, c=clusters)
plt.title("example4")

当您遍历簇并绘制 scatter 而不指定任何颜色时,将使用活动 属性 循环仪(颜色循环)的默认颜色。 属性 循环仪在 rcParams 中定义。它是通过使用的样式设置的;在你的情况下,使用 'fivethirtyeight'

print(plt.rcParams["axes.prop_cycle"])
> cycler('color', ['#008fd5', '#fc4f30', '#e5ae38', '#6d904f', '#8b8b8b', '#810f7c'])

前两种颜色('#008fd5'、'#fc4f30')是您在图中看到的颜色。

当您使用 scatterclusters 作为颜色参数时,这些值将通过颜色映射映射到颜色。如果未指定颜色图,它将采用 rcParam 中定义的默认颜色图。

print(plt.rcParams["image.cmap"])
> "viridis"

'fivethirtyeight' 样式没有定义任何特殊的颜色图,因此默认值不变。 (您在图片中观察到与 viridis 不同的色图是因为还有一些其他代码仍处于活动状态,但问题中未显示。)

此时我需要开始翻译;我认为您的问题实际上是如何使用与其中的颜色循环具有相同颜色的颜色图来获得单个散点图。 None 的预定义颜色映射中包含 5 到 8 种循环仪颜色。因此,您可以通过

手动定义该颜色图
import matplotlib.colors as mcolors
cmap = mcolors.ListedColormap(plt.rcParams['axes.prop_cycle'].by_key()['color'])

现在您需要一种索引颜色图的方法,因为您有离散的簇。

n = len(clusters.unique())
norm = mcolors.BoundaryNorm(np.arange(n+1)-0.5, n)

当然,这要求颜色图中的颜色数量大于或等于 类 的数量 - 这里就是这种情况。

把它们放在一起,(我添加了另一个类别,以使其更具说明性)

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.colors as mcolors

plt.style.use('fivethirtyeight') #relevant here!!

X=pd.Series([1, 2, 3, 4, 5, 11, 12, 13, 14, 15])
Y=pd.Series([1,1,1,1,1,2,2,2,2,2])
clusters=pd.Series([0,0,0,0,0,1,1,1,1,2])

cmap = mcolors.ListedColormap(plt.rcParams['axes.prop_cycle'].by_key()['color'])
n = len(clusters.unique())
norm = mcolors.BoundaryNorm(np.arange(n+1)-0.5, n)

plt.figure(figsize = (6, 4))
sc = plt.scatter(X,Y, c=clusters, cmap=cmap, norm=norm)
plt.colorbar(sc, ticks=clusters.unique())
plt.title("example4")

plt.show()