PAYATHON 2026

UpSetR 如何调整柱顶数字的旋转位置并单独设置颜色?

数据小陈

可以继续使用 UpSetR。先通过 number.colors 设置数字颜色;如果旋转后标签仍然重叠,还需要调整文字的对齐方式和位置。若当前安装版本没有该参数,可以修改生成图中的数字标签。

先确认当前函数是否支持独立配色

UpSetR 仓库中的 upset() 定义包含 number.colors。原问题没有给出安装版本和具体报错,还不能确定本地函数是否支持该参数。可以先检查实际调用的函数:UpSetR 参数定义。

packageVersion("UpSetR")
"number.colors" %in% names(formals(UpSetR::upset))

如果第二行返回 TRUE,可以这样分别设置颜色:

UpSetR::upset(
  df,
  sets = c("food", "drink", "house"),
  main.bar.color = "blue",
  number.colors = "red",
  show.numbers = "yes",
  number.angles = 45,
  text.scale = c(1, 1, 1, 1, 1, 2)
)

显式调用 UpSetR::upset() 可以避免误用其他包中的同名函数。如果检查返回 FALSE,不要向该函数传入 number.colors,可以用下面的方法直接修改标签颜色。

为什么只修改旋转角度仍会重叠?

旋转角度决定文字的朝向,对齐方式决定文字从柱顶向哪个方向展开。在所核对的实现中,数字标签由 geom_text() 绘制,固定设置了 vjust = -1,没有提供独立的水平对齐参数。只改变 number.angles,长数字仍可能伸入柱形区域。未指定独立数字颜色时,标签也会使用柱形颜色。主柱图实现。

可以把文字起点对齐到柱顶,向上留出少量间距,并增加图内顶部空间。

修改生成图中的数字标签

下面的代码使用问题中的 df。它保留蓝色柱形,将数字改为红色,使文字从柱顶附近向右上方延伸。

代码操作的是 p$Main_bar 中的图形对象。UpSetR 会先将主柱图转换为 gtable,因此不能像普通 ggplot 对象那样直接添加 geom_text()。图形转换代码。

library(UpSetR)
library(grid)

args <- list(
  data = df,
  sets = c("food", "drink", "house"),
  main.bar.color = "blue",
  show.numbers = "yes",
  number.angles = 45,
  text.scale = c(1, 1, 1, 1, 1, 2),
  mainbar.y.max = 80000
)

# 兼容没有 number.colors 参数的安装版本
if ("number.colors" %in% names(formals(UpSetR::upset))) {
  args$number.colors <- "red"
}

p <- do.call(UpSetR::upset, args)

# 找到主柱图的绘图区
panel_id <- which(p$Main_bar$layout$name == "panel")
if (length(panel_id) != 1L) {
  stop("未找到唯一的主柱图 panel,请检查当前版本的图形结构。")
}

panel <- p$Main_bar$grobs[[panel_id]]

# 标准主柱图中,数字标签对应一个 text grob
text_id <- which(vapply(
  panel$children,
  function(g) inherits(g, "text"),
  logical(1)
))

if (length(text_id) != 1L) {
  stop("未找到唯一的数字标签 grob,请检查 panel$children。")
}

labels <- panel$children[[text_id]]
labels$rot <- 45
labels$hjust <- 0
labels$vjust <- 0.5
labels$y <- labels$y + grid::unit(2, "mm")
labels$gp$col <- "red"

panel$children[[text_id]] <- labels
p$Main_bar$grobs[[panel_id]] <- panel

print(p)

其中,hjust = 0 让文字从起点展开,vjust = 0.5 将文字在垂直于文字方向的轴上居中,unit(2, "mm") 把标签整体上移,与柱顶留出间隔。

如果需要竖直显示,可以将 labels$rot <- 45 改为 labels$rot <- 90。调整角度或间距时,建议从创建 p 的步骤重新运行,以免位移重复累加。

顶部空间和适用范围

示例中的 mainbar.y.max = 80000 只为给出的数据预留空间。该数据的三个非空交集计数分别为 50000、30000 和 20000;实际六位数数据应根据最高柱形重新设置上限。旋转后的标签需要多少空间,还取决于字号和输出图的尺寸。

这段代码适用于主柱图保存为 gtable、数字标签位于单个 panel 中的实现。代码没有修改 UpSetR 的命名空间,但依赖其内部图形结构。如果检查时报错,应先查看 p$Main_bar$layout 和 panel$children,再定位标签,不要假定 grob 编号固定。以上代码未在提问者的具体 R 环境中运行验证。

备注:内容仅供参考。