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

如何在ggplot2绘图中添加紧贴副标题的居中二级副标题?

如何在ggplot2中添加紧贴副标题的二级副标题

问题描述

我想在ggplot2图表中添加标题、副标题和二级副标题,尝试用annotate添加二级副标题,但文本位于绘图区域内,和副标题间距过大;调整y参数会拉伸图表,无法缩短二者间距。请问怎么添加紧贴副标题、居中显示且字号更小的二级副标题?

原代码:

# Common packages loading
library(ggplot2)
library(reshape)
library(readxl)
library(ggrepel)
library(ggtext)


# Dataframe creation
Dati <- data.frame(
  Time = c("0w", "0w", "0w", "6w", "6w", "6w", "8w", "8w", "8w", "10w", "10w", "10w"),
  Peel_max = c(3.91, 4.4, 4.17, 3.24, 3.77, 2.91, 2.68, 2.79, 2.24, 1.84, 1.8, 1.54),
  Foil_break = c("Foil break", "Foil break", "Foil break", "Foil break", "Foil break", "Foil break", "", "", "", "", "", ""),
  FoilSide = c("A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C")
)


# Definition of the factors
Dati$Time = factor(Dati$Time, levels = c("0w","6w","8w","10w"))


# Generic graph creation
Graph2 <- ggplot(Dati, aes(x= `Time`, col=`FoilSide`)) +
  geom_point(aes(y= `Peel max`, color=`FoilSide`), shape = 1, size = 3.5) + 
  geom_line(aes(x=as.numeric(Dati$`Time`), y= `Peel max`, col=`FoilSide`)) +
  theme_classic() +
  scale_x_discrete(name="Time (Weeks)", expand=c(0.05, 0)) +
  ggtitle("This is the title", subtitle = "This is the subtitle") +
  theme(plot.title = element_text(hjust = 0.5), 
        plot.subtitle = element_text(hjust = 0.5))


# Addition of the SubSubtitle, which is placing it too below
Graph2 = Graph2 + 
  annotate("text", 
           x = mean(range(as.numeric(Dati$`Time`))),  
           y = 6,  # Set a negative value
           label = "Max peel measured when foil breaks, otherwise reported the average peel", 
           size = 2.5, fontface = "italic", hjust = 0.5)


Graph2

解决方案

你之前的问题根源是:annotate添加的文本属于绘图区域内的几何元素,而副标题属于标题区域的主题元素,二者不在同一图层,因此无法通过调整y值拉近间距,反而会拉伸绘图范围。下面是两种可行的解决方法:

方法1:用ggtext实现带样式的二级副标题(推荐)

利用你已加载的ggtext包,通过element_markdown可以在副标题中插入HTML样式的多行文本,让二级副标题紧贴主副标题,且能单独设置字号、字体样式:

Graph2 <- ggplot(Dati, aes(x= `Time`, col=`FoilSide`)) +
  geom_point(aes(y= `Peel max`, color=`FoilSide`), shape = 1, size = 3.5) + 
  geom_line(aes(x=as.numeric(Dati$`Time`), y= `Peel max`, col=`FoilSide`)) +
  theme_classic() +
  scale_x_discrete(name="Time (Weeks)", expand=c(0.05, 0)) +
  # 在subtitle中用<br>换行,用span设置二级副标题的样式
  ggtitle("This is the title", 
          subtitle = "This is the subtitle<br><span style='font-size:8pt; font-style:italic;'>Max peel measured when foil breaks, otherwise reported the average peel</span>") +
  theme(
    plot.title = element_text(hjust = 0.5), 
    # 用element_markdown渲染markdown/HTML语法
    plot.subtitle = element_markdown(hjust = 0.5, margin = margin(b = 10)) # 可调整底部margin控制与绘图区的间距
  )

Graph2

方法2:通过换行和文本样式调整实现

如果不想用HTML/markdown,也可以直接用\n换行,配合element_text的参数调整样式:

Graph2 <- ggplot(Dati, aes(x= `Time`, col=`FoilSide`)) +
  geom_point(aes(y= `Peel max`, color=`FoilSide`), shape = 1, size = 3.5) + 
  geom_line(aes(x=as.numeric(Dati$`Time`), y= `Peel max`, col=`FoilSide`)) +
  theme_classic() +
  scale_x_discrete(name="Time (Weeks)", expand=c(0.05, 0)) +
  # 用\n分隔主副标题和二级副标题
  ggtitle("This is the title", 
          subtitle = "This is the subtitle\nMax peel measured when foil breaks, otherwise reported the average peel") +
  theme(
    plot.title = element_text(hjust = 0.5), 
    plot.subtitle = element_text(hjust = 0.5, 
                                 size = 9, # 统一设置副标题字号,若要单独区分二级副标题推荐方法1
                                 lineheight = 1.2,
                                 margin = margin(b = 10)),
    plot.title.position = "plot" # 可选,让标题和副标题对齐整个绘图区宽度
  )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:54:52