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

R调用ggplotly转换含annotation_raster图表报条件长度大于1错误

问题描述

运行Stack Overflow问题《embed image: ggplot to plotly date issue》中的示例代码时触发运行报错,原代码如下:

library(ggplot2)
library(png)
library(RCurl)
library(plotly)
mydf <- data.frame(date = 
                   as.Date(c("01/01/1998", "10/01/1998", "15/01/1998", 
                             "25/01/1998", "01/02/1998", "12/02/1998", "20/02/1998"), "%d/%m/%Y"),
                 counts = c(12, 10, 2, 24, 15, 1, 14),
                 image = c(NA, "https://www.r-project.org/logo/Rlogo.png", NA, NA, 
                           "https://www.r-project.org/logo/Rlogo.png", NA, NA))
mydf

# 计算图片显示的宽高
yHeight <- (max(mydf$counts) - min(mydf$counts)) * 0.05
xWidth <- (max(as.numeric(mydf$date)) - min(as.numeric(mydf$date))) * 0.05

# 绘制基础ggplot图
gg2 <- ggplot(mydf, aes(date, counts)) + 
  geom_line()

# 遍历数据行添加图片标注
for (x in 1:nrow(mydf)) {
  row <- mydf[x, ]
  if(!is.na(row$image)){
    # 读取远程图片
    img <- readPNG(getURLContent(row$image))
    # 通过annotation_raster添加图片图层
    gg2 <- gg2 + annotation_raster(img, 
                            xmin = as.numeric(row$date) - xWidth/2, 
                            xmax = as.numeric(row$date) + xWidth/2, 
                            ymin = row$counts - yHeight/2, 
                            ymax = row$counts + yHeight/2)
  }
}

ggplotly(gg2)

运行后抛出的报错信息为:

Error in if (RasterGeom/length(geoms) > 0.5) "above" else "below" : 
  the condition has length > 1
报错原因

该报错源于ggplotly转换逻辑的兼容缺陷:当ggplot对象通过循环叠加多个annotation_raster栅格图层时,ggplotly内部用于判断栅格显示层级的代码未做输入值收敛,直接将长度大于1的向量传入if条件判断;而R语言中if结构仅接受单逻辑值输入,因此直接触发运行错误。

解决方案

放弃在ggplot层循环叠加annotation_raster再转换为plotly对象的实现路径,直接使用plotly原生的图片标注接口添加嵌入图片,从根源上规避图层转换的兼容问题,修正后的可运行代码如下:

library(ggplot2)
library(plotly)
mydf <- data.frame(date = 
                   as.Date(c("01/01/1998", "10/01/1998", "15/01/1998", 
                             "25/01/1998", "01/02/1998", "12/02/1998", "20/02/1998"), "%d/%m/%Y"),
                 counts = c(12, 10, 2, 24, 15, 1, 14),
                 image = c(NA, "https://www.r-project.org/logo/Rlogo.png", NA, NA, 
                           "https://www.r-project.org/logo/Rlogo.png", NA, NA))

# 计算图片显示宽高
yHeight <- (max(mydf$counts) - min(mydf$counts)) * 0.05
xWidth <- (max(as.numeric(mydf$date)) - min(as.numeric(mydf$date))) * 0.05

# 生成基础plotly线图
p <- plot_ly(mydf, x = ~date, y = ~counts, type = 'scatter', mode = 'lines')

# 构造图片标注配置列表
img_list <- list()
valid_img_row <- which(!is.na(mydf$image))
for (i in seq_along(valid_img_row)) {
  row <- mydf[valid_img_row[i], ]
  img_list[[i]] <- list(
    source = row$image,
    x = as.numeric(row$date),
    y = row$counts,
    sizex = xWidth,
    sizey = yHeight,
    xref = "x",
    yref = "y",
    xanchor = "center",
    yanchor = "middle"
  )
}

# 批量添加图片并输出图表
p <- p %>% layout(images = img_list)
p

运行上述代码即可正常生成带嵌入图片的交互式折线图,不会触发此前的层级判断报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 19:56:50