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

R使用plotly绘图报plot.new has not been called yet错误如何解决

报错核心原因

你遇到这个报错的本质是混用了两套完全独立的R绘图体系的语法:

  • axis()、abline()、mtext()、pch、cex、ylim、axes这些函数和参数,全部属于R内置的base基础绘图系统,只能在R本地的栅格绘图设备中运行,调用时要求已经通过plot()等base绘图命令启动了绘图窗口。
  • plot_ly()生成的是plotly的交互式Web绘图对象,和base绘图系统完全不互通,你在layout()里直接传入axis()这类base函数调用时,R会尝试寻找base系统的活跃绘图设备,找不到就直接抛出plot.new has not been called yet错误。

你的代码里还存在几个会导致后续运行失败的问题:

  • plot_ly中映射的y = ~res列在你提供的示例数据中不存在,示例数据只有Age和Pertubation两列
  • 保存环节错误地将原生plotly对象传入了ggplotly(),这个函数仅用于转换ggplot2生成的绘图对象,直接传入plotly对象会触发类型错误
  • plotly的layout()函数仅接受自身约定的配置参数,不支持直接传入base绘图的函数调用
修复方案
  1. 全部替换base绘图逻辑为plotly原生语法:
    • 坐标轴刻度、字号配置:写入layout()对应的xaxis/yaxis/yaxis2(右侧副轴)参数中,不再使用axis()
    • 参考线:通过layout()的shapes参数配置,不再使用abline()
    • 边距/轴标题:通过轴配置的title参数设置,不再使用mtext()
    • 点样式、轴范围、字号:分别写入marker、轴的range、font相关参数,不再使用base绘图的pch/cex/ylim参数
  2. 修正对象调用逻辑:
    • 将y轴映射替换为你实际需要绘制的列(示例数据中为Pertubation)
    • 保存时直接将plotly对象传入saveWidget(),不再嵌套ggplotly()

修复后的可运行参考代码:

# 加载依赖
library(plotly)
library(htmlwidgets)

# 示例数据
Age <-c(69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183)
Pertubation <- c(0.002967936,-0.794788368,-1.561544673,-2.938300977,-2.956057282,-3.724813586,-3.84656989,-4.000326195,-3.491082499,-3.705838803,-3.008595108,-3.439351412,-2.518107716,-2.108864021,-1.892620325,-2.175376629,-2.547132934,-2.694889238,-3.985645543,-2.702401847,-3.203158151,-3.238914456,-2.60867076,-2.564427064,-3.254183369,-1.973939673,-0.731695977,-0.625452282,-0.966208586,-0.811964891,-0.018721195,0.320522501,-0.227233804,-0.046990108,-0.820746412,-0.846502717,1.067740979,1.470984675,1.00222837,0.448472066,1.139715762,1.275959457,0.989203153,0.904446848,0.607690544,0.20693424,1.084177935,1.114421631,0.625665327,0.292909022,-0.833847282,-2.208603586,-3.397359891,-4.339116195,-4.950872499,-5.518628804,-6.992385108,-7.023141413,-8.193897717,-8.580654021,-9.428410326,-10.92316663,-11.37392293,-12.21167924,-12.77643554,-13.14219185,-13.67394815,-14.19370446,-14.16046076,-15.29121706,-16.06197337,-16.11472967,-16.29348598,-17.62424228,-17.79699859,-19.42675489,-19.6625112,-20.3642675,-21.4460238,-22.05378011,-23.87553641,-24.06129272,-25.00604902,-25.80180533,-26.77656163,-27.40431793,-28.86407424,-29.45483054,-29.37758685,-30.48534315,-30.07209946,-29.86985576,-29.82561207,-30.46936837,-30.56412467,-30.24788098,-29.40463728,-29.76939359,-29.11314989,-29.0989062,-29.2466625,-29.1654188,-29.28217511,-29.11493141,-28.44568772,-28.65344402,-28.43520033,-28.71795663,-29.06871293,-29.66546924,-28.39422554,-29.68398185,-29.73973815,-29.34349446,-29.45325076)
plot_df <- data.frame(Age, Pertubation)

# 按需替换为你代码中的实际变量值
i <- 1
lambda <- 0.5
crit1 <- -5
# 替换为原代码中dif$eval_day生成的刻度序列
x_ticks <- seq(min(plot_df$Age), max(plot_df$Age), by = 5)

# 生成绘图对象
Pertubation_graph <- plot_ly(plot_df, x = ~Age, y = ~Pertubation,
                             type = "scatter", mode = "markers",
                             # 对应原代码pch=10、cex=0.5的点样式
                             marker = list(symbol = 10, size = 5)
                             ) %>%
  layout(
    title = paste0("Pig ID:", i, ", Lambda =", lambda, "<br>Difference between CFI and TTC"),
    plot_bgcolor = "#ffffff",
    # 底部X轴配置,对应原axis(1)设置
    xaxis = list(
      title = "Age (d)",
      tickmode = "array",
      tickvals = x_ticks,
      tickfont = list(size = 13.2), # 对应cex.axis=1.1
      titlefont = list(size = 14.4) # 对应cex.lab=1.2
    ),
    # 左侧Y轴配置,对应原axis(2)设置
    yaxis = list(
      title = "Amount of difference: CFI - TTC (kg)",
      range = c(min(plot_df$Pertubation) - 1, max(plot_df$Pertubation) + 1), # 替换为原代码的ylim范围
      tickfont = list(size = 13.2),
      titlefont = list(size = 14.4)
    ),
    # 右侧Y轴配置,对应原axis(4)设置
    yaxis2 = list(
      title = "Percentage of difference: CFI - TTC (%)",
      overlaying = "y",
      side = "right",
      tickfont = list(size = 13.2, color = "blue"),
      titlefont = list(size = 14.4, color = "blue"),
      color = "blue"
    ),
    titlefont = list(size = 18), # 对应cex.main=1.5
    # 参考线配置,对应原abline设置
    shapes = list(
      list(type = "line", x0 = min(plot_df$Age), x1 = max(plot_df$Age),
           y0 = crit1, y1 = crit1, line = list(color = "red", dash = "dash")),
      list(type = "line", x0 = min(plot_df$Age), x1 = max(plot_df$Age),
           y0 = 0, y1 = 0, line = list(color = "red"))
    )
  )

# 保存为HTML文件,替换为你实际的存储路径
saveWidget(Pertubation_graph, file = "pertubation_plot.html")

额外说明

  • base绘图的cex是相对默认字号(12px)的缩放倍数,直接用12乘以对应cex值就能得到plotly中匹配的字号
  • 如果需要给右侧Y轴绑定对应的数据,只需要新增一个标记为yaxis = "y2"的绘图trace即可
  • 后续使用plotly绘图时不要插入任何base绘图函数,两类绘图系统的设备完全独立,无法互相操作

内容的提问来源于stack exchange,提问作者Lam Tùng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:21:42