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

如何在ade4的s.class图中按两类变量分设椭圆与符号颜色

Hey there! I totally get your frustration—ade4's s.class() function does tie the grouping factor to both the ellipses and point styling by default, which makes separating those two variables tricky. But don't worry, we can work around this by splitting the plotting into two separate steps: first drawing the morphometric cluster ellipses, then overlaying the points colored by genetic cluster (plus handling those NA ggpop samples).

Step 1: Prep your data

First, let's clean up the grouping variables and handle those NA ggpop entries by creating a dedicated color group (so we can style those samples differently):

# Load ade4 if you haven't already
library(ade4)

# Convert grouping columns to factors (critical for consistent coloring)
df$Morph.cluster <- as.factor(df$Morph.cluster)
df$ALL <- as.factor(df$ALL)

# Create a color group: use ALL, but mark NA ggpop samples as a separate category
df$color_group <- df$ALL
df$color_group[is.na(df$ggpop)] <- "Missing"

Step 2: Set up the dudi object (required for ade4 plotting)

ade4 relies on ordination objects for most plots, so let's create one from your RW1 and RW2 data:

# Create a PCA dudi from RW1 and RW2 (we just need the scores for plotting)
dudi_rw <- dudi.pca(df[, c("RW1", "RW2")], scannf = FALSE, nf = 2)

Step 3: Draw the morphometric cluster ellipses (no points yet)

We'll use s.class() to draw the ellipses based on Morph.cluster, but tell it not to plot any points:

# Plot ellipses for Morph.cluster, hide points
s.class(dudi_rw$li, 
        fac = df$Morph.cluster,
        col = 1:nlevels(df$Morph.cluster),  # Color for ellipse borders
        lwd = 2,  # Make ellipses easier to see
        show.points = FALSE,  # Don't draw the default points
        ellipse = TRUE)  # Ensure ellipses are drawn

Step 4: Overlay points colored by genetic cluster (with NA handling)

Now use base R's points() to add your data points, styling them based on color_group and marking NA ggpop samples with a distinct symbol:

# Define a custom color palette for your genetic clusters + missing samples
# Replace the values with your actual cluster names/colors!
color_palette <- c(
  "Cluster1" = "#E69F00",
  "Cluster2" = "#56B4E9",
  "Cluster3" = "#009E73",
  "Missing" = "#999999"
)

# Add the points: solid circles for non-NA, hollow for NA ggpop
points(dudi_rw$li$RW1, dudi_rw$li$RW2,
       col = color_palette[df$color_group],
       pch = ifelse(is.na(df$ggpop), 1, 19),  # 1 = hollow circle, 19 = solid
       cex = 1.2)  # Adjust point size if needed

Step 5: Add clear legends

Since we have two separate grouping systems, add two legends to make the plot easy to interpret:

# Legend for Morph.cluster ellipses
legend("topright",
       legend = levels(df$Morph.cluster),
       col = 1:nlevels(df$Morph.cluster),
       lty = 1, lwd = 2,
       title = "Morphometric Cluster")

# Legend for genetic cluster points
legend("bottomright",
       legend = names(color_palette),
       col = color_palette,
       pch = c(19, 19, 19, 1),  # Match pch values from points()
       title = "Genetic Cluster (ALL)")

Why this works

The key here is breaking the plot into two parts: s.class() handles the ellipse grouping (tied to Morph.cluster), while base R's points() gives us full control over point coloring/symbols tied to ALL (and our custom missing category). This bypasses the default link between fac and point styling in s.class().

内容的提问来源于stack exchange,提问作者Ella Bowles

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:38:28