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

使用facet_grid时,如何在ggplot2的离散刻度次坐标轴添加标题?

问题描述

我使用ggplot2绘制了分面热力图,希望在分面区域的顶部添加蓝色标题“x1”,在分面区域的右侧添加蓝色标题“y1”,实现类似参考图的效果。

数据

dat <-
structure(list(x0 = c(15, 30, 45, 15, 30, 45, 15, 30, 45, 15, 
30, 45, 15, 30, 45, 15, 30, 45, 15, 30, 45, 15, 30, 45, 15, 30, 
45, 15, 30, 45, 15, 30, 45, 15, 30, 45, 15, 30, 45, 15, 30, 45, 
15, 30, 45, 15, 30, 45, 15, 30, 45, 15, 30, 45, 15, 30, 45, 15, 
30, 45, 15, 30, 45, 15, 30, 45, 15, 30, 45, 15, 30, 45, 15, 30, 
45, 15, 30, 45, 15, 30, 45), y0 = c(2, 2, 2, 7, 7, 7, 20, 20, 
20, 2, 2, 2, 7, 7, 7, 20, 20, 20, 2, 2, 2, 7, 7, 7, 20, 20, 20, 
2, 2, 2, 7, 7, 7, 20, 20, 20, 2, 2, 2, 7, 7, 7, 20, 20, 20, 2, 
2, 2, 7, 7, 7, 20, 20, 20, 2, 2, 2, 7, 7, 7, 20, 20, 20, 2, 2, 
2, 7, 7, 7, 20, 20, 20, 2, 2, 2, 7, 7, 7, 20, 20, 20), x1 = c(2, 
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 
4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 
3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4), y1 = c(50, 
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 
50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 250, 250, 250, 250, 250, 
250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 
250, 250, 250, 250, 250, 250, 250, 250, 250, 500, 500, 500, 500, 
500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 
500, 500, 500, 500, 500, 500, 500, 500, 500, 500), percent = c(0.99, 
2.69, 4.91, -0.23, -0.22, 0.14, -1.5, -3.15, -4.61, 0.53, 1.65, 
3.43, -0.56, -0.81, -0.36, -0.34, -0.79, -1.21, -0.2, -0.29, 
-0.13, -0.64, -1.33, -1.59, 0.29, 0.68, 1.23, -1.16, -3.04, -4.94, 
-0.46, -1.23, -2.19, -1.06, -2.53, -3.88, 0.06, 0.11, 0.2, -0.42, 
-1.01, -1.38, -2.49, -5.71, -7.74, 0.09, 0.43, 1.4, -0.8, -1.38, 
-0.84, -2.13, -4.74, -6.41, -0.27, -0.64, -1.05, -0.27, -0.71, 
-1.22, -0.6, -1.46, -2.3, 0.12, 0.3, 0.43, 0.12, 0.46, 0.74, 
-0.44, -1, -1.61, 0.88, 2.04, 3.11, 0.68, 1.64, 2.48, -0.98, 
-2.14, -3.11)), class = "data.frame", row.names = c(NA, -81L))

原代码

library(ggplot2)
ggplot(dat, aes(x = factor(x0), y = factor(y0))) + 
  geom_tile(aes(fill = percent)) +
  scale_fill_gradientn(
    colours=c("red2", "white", "green"),
    values = scales::rescale(c(-10, 0, 5)),
    limits=c(-10, 5)) +
  geom_text(aes(label = round(percent, 0))) + 
  facet_grid(y1 ~ x1) +
  theme_bw() +
  theme(axis.text.x = element_text(colour="black",size=13.1, angle=0, margin=margin(b=4), hjust = 0.5, vjust = 0.5)) +
  theme(axis.text.y = element_text(colour="black",size=13.1,  margin=margin(l=6), hjust = -0.1, vjust = 0.5)) +
  theme(panel.grid.major=element_line(colour="white",size=0.1))+
  theme(axis.ticks=element_blank()) +
  theme(plot.margin=unit(c(1.2,0.5,0.05,0.05),"cm")) +
  theme(legend.position = "right", legend.box.margin=margin(-10,-10,-10,-10)) +
  theme(strip.text = element_text(size = 12, color = "black")) +
  xlab(~paste("x0")) +
  ylab(~paste("y0")) +
  theme(axis.title=element_text(size=18))

解决方案

我们可以借助grid包的文本对象,结合annotation_custom添加全局标题,并调整绘图边距让标题显示完整:

library(ggplot2)
library(grid)

# 绘制基础图形
p <- ggplot(dat, aes(x = factor(x0), y = factor(y0))) + 
  geom_tile(aes(fill = percent)) +
  scale_fill_gradientn(
    colours=c("red2", "white", "green"),
    values = scales::rescale(c(-10, 0, 5)),
    limits=c(-10, 5)) +
  geom_text(aes(label = round(percent, 0))) + 
  facet_grid(y1 ~ x1) +
  theme_bw() +
  theme(axis.text.x = element_text(colour="black",size=13.1, angle=0, margin=margin(b=4), hjust = 0.5, vjust = 0.5)) +
  theme(axis.text.y = element_text(colour="black",size=13.1,  margin=margin(l=6), hjust = -0.1, vjust = 0.5)) +
  theme(panel.grid.major=element_line(colour="white",size=0.1))+
  theme(axis.ticks=element_blank()) +
  theme(plot.margin=unit(c(2, 2, 0.05, 0.05),"cm")) +  # 增大顶部和右侧边距,容纳新标题
  theme(legend.position = "right", legend.box.margin=margin(-10,-10,-10,-10)) +
  theme(strip.text = element_text(size = 12, color = "black")) +
  xlab(~paste("x0")) +
  ylab(~paste("y0")) +
  theme(axis.title=element_text(size=18))

# 添加顶部蓝色标题"x1"
p <- p + annotation_custom(
  grob = textGrob(label = "x1", color = "blue", size = 6, hjust = 0.5),
  xmin = -Inf, xmax = Inf, ymin = Inf, ymax = Inf
)

# 添加右侧蓝色标题"y1"(旋转90度)
p <- p + annotation_custom(
  grob = textGrob(label = "y1", color = "blue", size = 6, rot = 90, hjust = 0.5),
  xmin = Inf, xmax = Inf, ymin = -Inf, ymax = Inf
)

# 关闭面板裁剪,让外部的标题显示出来
gt <- ggplot_gtable(ggplot_build(p))
gt$layout$clip[gt$layout$name == "panel"] <- "off"
grid.draw(gt)

说明

  1. 调整plot.margin增大顶部和右侧边距,避免标题被裁剪;
  2. 使用annotation_custom添加全局文本,textGrob设置颜色和字号;
  3. 关闭面板裁剪(clip = "off"),确保超出面板范围的标题能正常显示;
  4. 可以通过调整textGrob的size参数修改标题字号,hjust调整水平对齐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 17:24:52