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

使用ggplot2+plotly实现图像坐标轴标签遇格式失效问题求助

问题:Plotly 转换后 ggtext 的图像 X 轴标签失效

我需要制作一个以图像为X轴标签的柱状图,同时保留Plotly的交互注释功能。但使用plotlyOutput和renderPlotly时,原本通过ggtext::element_markdown()解析的图像标签被当作原始文本显示;换成plotOutput和renderPlot则能正常渲染图像标签,推测是Plotly与ggtext的markdown解析功能存在冲突。

原代码如下:

library("shiny")
library('bslib')
library("ggplot2")
library('ggtext')
library('plotly')

# 示例数据,项目的www/目录下有apple.png、mangosteen.png等图片
df <- data.frame('fruit' = c('Apple', 'Mangosteen', 'Pear', 'Banana'),
             'quantity' = c(5, 4, 1, 3))
ui <- page_fluid(plotlyOutput('groceries_plot'))

server <- function(input, output) {  
  # 生成可被ggtext解析的HTML图像标签
  df <- df %>% mutate(html_img = paste0("<img src='www/",tolower(fruit),".png'",
                                        " height = '95'><br>", fruit))

  output$groceries_plot <- renderPlotly({
    ggplot(df, aes(x = html_img, y = quantity, fill = fruit)) +
      geom_col() +
      theme_light() +
      theme(axis.text.x = ggtext::element_markdown())
    })
}

runApp(list(ui = ui, server = server))

解决方案:用Plotly原生方法实现图像X轴标签

Plotly在转换ggplot对象时不会保留ggtext的markdown解析逻辑,因此需要直接使用Plotly的API来定义带图像的X轴标签,替代ggtext的实现:

library("shiny")
library('bslib')
library("ggplot2")
library('plotly')

# 示例数据,项目的www/目录下有apple.png、mangosteen.png等图片
df <- data.frame('fruit' = c('Apple', 'Mangosteen', 'Pear', 'Banana'),
                 'quantity' = c(5, 4, 1, 3))
ui <- page_fluid(plotlyOutput('groceries_plot'))

server <- function(input, output) {  
  # 生成Plotly可用的HTML图像标签(Shiny会自动从www目录读取资源,无需加www/前缀)
  df <- df %>% mutate(plotly_img = paste0("<img src='",tolower(fruit),".png'",
                                        " height='95'><br>", fruit))

  output$groceries_plot <- renderPlotly({
    # 用原始fruit字段作为X轴,避免HTML文本干扰
    p <- ggplot(df, aes(x = fruit, y = quantity, fill = fruit)) +
      geom_col() +
      theme_light() +
      # 隐藏ggplot原生X轴文本,后续用Plotly自定义刻度替代
      theme(axis.text.x = element_blank())
    
    # 转换为Plotly并自定义X轴
    ggplotly(p) %>%
      layout(
        xaxis = list(
          tickmode = "array",
          tickvals = df$fruit,
          ticktext = df$plotly_img,
          tickangle = 0,
          # 调整X轴底部边距,防止图像标签被截断
          margin = list(b = 100)
        )
      )
  })
}

runApp(list(ui = ui, server = server))

关键说明:

  • Plotly的轴刻度文本支持HTML格式,因此可以直接用<img>标签嵌入图像
  • Shiny中访问www目录下的资源无需添加www/前缀,路径直接写文件名即可
  • 先隐藏ggplot的原生X轴文本,避免与Plotly自定义刻度重复显示
  • 调整X轴底部边距margin.b,防止图像标签被页面底部截断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 10:17:05