You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中为轮廓图的不同簇设置差异化纹理?

解决轮廓图分簇设置不同纹理的问题

嘿,这个坑我之前踩过!直接用plot函数全局设置density和angle确实会让所有簇的纹理同步变化,要实现分簇差异化纹理,核心思路是逐个绘制每个簇的轮廓条,这样就能给每个簇单独指定纹理参数了。下面分Python和R两种常用场景给你具体方案:

Python(Matplotlib)实现

假设你用的是sklearn计算轮廓系数,结合matplotlib绘图:

import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score
import numpy as np

# 1. 准备数据和聚类结果(替换成你的真实数据即可)
X = np.random.rand(150, 2)  # 示例:150个样本,2个特征
kmeans = KMeans(n_clusters=3, random_state=42)
labels = kmeans.fit_predict(X)

# 2. 计算轮廓系数
silhouette_vals = silhouette_samples(X, labels)
sil_avg = silhouette_score(X, labels)  # 平均轮廓系数

# 3. 定义每个簇的专属参数(颜色、纹理密度、角度)
cluster_params = [
    {"color": "#1f77b4", "density": 5, "angle": 0},
    {"color": "#ff7f0e", "density": 10, "angle": 45},
    {"color": "#2ca02c", "density": 15, "angle": 90}
]

# 4. 逐个绘制每个簇的轮廓条
fig, ax = plt.subplots(figsize=(8, 6))
y_lower = 10  # 初始y轴位置

for cluster_idx in range(3):
    # 提取当前簇的轮廓系数并排序
    cluster_sil = silhouette_vals[labels == cluster_idx]
    cluster_sil.sort()
    cluster_size = cluster_sil.shape[0]
    y_upper = y_lower + cluster_size

    # 绘制带纹理的填充区域
    ax.fill_betweenx(
        np.arange(y_lower, y_upper),
        0, cluster_sil,
        facecolor=cluster_params[cluster_idx]["color"],
        edgecolor=cluster_params[cluster_idx]["color"],
        density=cluster_params[cluster_idx]["density"],
        angle=cluster_params[cluster_idx]["angle"]
    )
    # 添加簇编号标签
    ax.text(-0.05, y_lower + cluster_size/2, str(cluster_idx + 1))
    y_lower = y_upper + 10  # 簇之间留空白间距

# 添加平均轮廓线
ax.axvline(x=sil_avg, color="red", linestyle="--", label="Average Silhouette Score")
ax.set_title("Silhouette Plot with Cluster-specific Hatching")
ax.set_xlabel("Silhouette Coefficient Value")
ax.set_ylabel("Cluster")
ax.legend()
plt.show()

R(ggplot2 + ggpattern)实现

如果用R语言,推荐结合ggpattern包实现自定义纹理:

library(cluster)
library(ggplot2)
library(ggpattern)

# 1. 准备数据和聚类结果(示例用iris数据集)
data(iris)
X <- iris[, 1:4]
km_model <- kmeans(X, 3)
sil_results <- silhouette(km_model$cluster, dist(X))
sil_df <- as.data.frame(sil_results)

# 2. 定义每个簇的纹理参数
cluster_patterns <- list(
  cluster1 = list(pattern = "stripe", density = 0.1, angle = 0),
  cluster2 = list(pattern = "crosshatch", density = 0.2, angle = 45),
  cluster3 = list(pattern = "dot", density = 0.3, angle = 90)
)

# 3. 绘制分簇纹理的轮廓图
ggplot(sil_df, aes(x = sil_width, y = reorder(cluster, sil_width))) +
  geom_pattern_area(
    aes(pattern = factor(cluster), fill = factor(cluster)),
    pattern_density = c(cluster_patterns$cluster1$density, 
                        cluster_patterns$cluster2$density, 
                        cluster_patterns$cluster3$density),
    pattern_angle = c(cluster_patterns$cluster1$angle, 
                      cluster_patterns$cluster2$angle, 
                      cluster_patterns$cluster3$angle),
    pattern_fill = "black"
  ) +
  scale_pattern_manual(values = c("stripe", "crosshatch", "dot")) +
  geom_vline(xintercept = mean(sil_df$sil_width), linetype = "dashed", color = "red") +
  labs(
    title = "Silhouette Plot with Cluster-specific Textures",
    x = "Silhouette Width", y = "Cluster",
    fill = "Cluster", pattern = "Texture Pattern"
  ) +
  theme_minimal()

核心原理

原来的plot函数会把density和angle作为全局参数应用到所有元素上,而通过循环拆分每个簇单独绘制,我们可以为每个簇的填充区域传递独立的纹理参数,从而实现分簇纹理差异化。

内容的提问来源于stack exchange,提问作者K.-T. Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:33:15