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

使用ggtext的element_markdown()渲染ggplot2文本时重叠问题求助

ggplot2结合ggtext渲染Markdown文本重叠问题的解决办法

问题描述

尝试在ggplot2图表的标题、副标题、说明文本及图例中使用Markdown格式文本,图例文本需通过ifelse语句根据变量动态生成(其中一种场景需将部分文本设为斜体),因此使用ggtext包的element_markdown()函数,用*包裹目标文本。但渲染后文本紧凑重叠,效果极差。调整字体大小、样式、字体族及边距均无效,尝试用expression结合paste/glue等替代方法,但ifelse语句导致实现困难,甚至用UNICODE符号输入也未成功。

运行环境:R版本4.2.1(2022-06-23),macOS Monterey 12.5.1,RStudio版本2022.7.1.554(Spotted Wakerobin),ggtext包版本0.1.1。

最小示例代码

library(tidyverse)
library(glue)
library(ggtext)

random_variable <- TRUE

iris %>% 
    ggplot(aes(x = Species, y = Sepal.Width)) + 
    geom_boxplot(show.legend = F, col = 'cadetblue4') +
    stat_summary(fun = mean, geom = 'point', shape = 18, size = 3, aes(col = 'mean')) +
    geom_hline(aes(yintercept = 2, col = '1st'), size = .5, lty = 2) +
    geom_hline(aes(yintercept = 3, col = '2nd'), size = .5, lty = 2) +
    geom_hline(aes(yintercept = 4, col = '3rd'), size = .5, lty = 2) +
    scale_colour_manual(name = 'Title without markdown', 
                        values = c('1st' = 'slateblue2', '2nd' = 'coral4', '3rd' = 'red2', 'mean' = 'black'),
                        labels = c('Sub<sub>1</sub>', 'Sup<sup>2</sup>', 'Both<sub>3</sub><sup>10</sup>', 
                                   paste('Some', ifelse(random_variable, yes = '*markdown* text here', no = 'not markdown text here'), 'and then some more text here.')),
                        guide = guide_legend(override.aes = list(
                            linetype = c(rep('dashed', 3), 'blank'),
                            shape = c(rep(NA, 3), 18)))) + 
    labs(title = paste0("This is a test of element_", ifelse(T, yes = '*markdown*', no = 'text'), " with the Iris dataset!"),
         subtitle = "Subtitle with **boldface text** and *italicised text* -- Not working at all…",
         caption = "THIS SENTENCE DEFINITELY HAS WHITESPACES!^{23}") +
    theme(
          # TITLES AND CAPTION
          plot.title = element_markdown(family="Times", face = "bold", size=15),
          plot.subtitle = element_markdown(family="Times", size=10),
          plot.caption = element_markdown(family = "Times", face = "bold", size = 11),
          
          # LEGEND SETTINGS
          legend.position = 'bottom',
          legend.key.size = unit(1.75, 'line'),
          legend.spacing.x = unit(.1, 'cm'),
          legend.title = element_markdown(size = 12, face = 'bold', family = 'Times', 
                                      margin = margin(r = .25, unit = 'cm')),
          legend.text = element_markdown(size = 13, face = 'bold', family = 'Times', 
                                     margin = margin(r = .5, unit = 'cm')),
          legend.key =  element_blank())

示例输出

最小示例输出

解决办法

1. 更新ggtext包到最新版本

你使用的ggtext 0.1.1版本存在文本排版的底层bug,后续版本已修复该问题。执行以下代码更新:

install.packages("ggtext")

2. 优化文本构造与排版参数

核心修改点:

  • 用glue替代paste构造动态文本,避免空格丢失或格式解析异常
  • 给所有element_markdown()添加lineheight参数,强制设置行高,解决文本重叠
  • 调整图例布局参数,给长文本留出足够空间

修改后的完整代码

library(tidyverse)
library(glue)
library(ggtext)

random_variable <- TRUE

# 用glue构造图例标签,语法更清晰
legend_labels <- c(
  'Sub<sub>1</sub>', 
  'Sup<sup>2</sup>', 
  'Both<sub>3</sub><sup>10</sup>', 
  glue('Some {ifelse(random_variable, "*markdown* text here", "not markdown text here")} and then some more text here.')
)

iris %>% 
  ggplot(aes(x = Species, y = Sepal.Width)) + 
  geom_boxplot(show.legend = F, col = 'cadetblue4') +
  stat_summary(fun = mean, geom = 'point', shape = 18, size = 3, aes(col = 'mean')) +
  geom_hline(aes(yintercept = 2, col = '1st'), size = .5, lty = 2) +
  geom_hline(aes(yintercept = 3, col = '2nd'), size = .5, lty = 2) +
  geom_hline(aes(yintercept = 4, col = '3rd'), size = .5, lty = 2) +
  scale_colour_manual(
    name = 'Title without markdown', 
    values = c('1st' = 'slateblue2', '2nd' = 'coral4', '3rd' = 'red2', 'mean' = 'black'),
    labels = legend_labels,
    guide = guide_legend(
      override.aes = list(
        linetype = c(rep('dashed', 3), 'blank'),
        shape = c(rep(NA, 3), 18)
      ),
      # 图例项换行显示,避免横向挤压
      nrow = 2
    )
  ) + 
  labs(
    title = glue("This is a test of element_{ifelse(TRUE, '*markdown*', 'text')} with the Iris dataset!"),
    subtitle = "Subtitle with **boldface text** and *italicised text* -- Now working correctly!",
    caption = "THIS SENTENCE DEFINITELY HAS WHITESPACES!^{23}"
  ) +
  theme(
    # 标题与说明文本:添加lineheight参数
    plot.title = element_markdown(family="Times", face = "bold", size=15, lineheight = 1.2),
    plot.subtitle = element_markdown(family="Times", size=10, lineheight = 1.2),
    plot.caption = element_markdown(family = "Times", face = "bold", size = 11, lineheight = 1.2),
    
    # 图例设置:调整行高与间距
    legend.position = 'bottom',
    legend.key.size = unit(2, 'line'),
    legend.spacing.x = unit(.3, 'cm'),
    legend.spacing.y = unit(.2, 'cm'),
    legend.title = element_markdown(size = 12, face = 'bold', family = 'Times', 
                                    margin = margin(r = .25, unit = 'cm'), lineheight = 1.2),
    legend.text = element_markdown(size = 13, face = 'bold', family = 'Times', 
                                   margin = margin(r = .5, unit = 'cm'), lineheight = 1.2),
    legend.key =  element_blank()
  )

效果说明

  • 更新ggtext包后,底层排版bug修复,文本不再重叠
  • lineheight参数确保文本行之间有足够间距
  • 图例设置nrow=2让长标签换行,避免横向空间不足
  • glue让动态文本的构造更直观,格式解析更准确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 22:25:17