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 环境中运行验证。
备注:内容仅供参考。
