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

Plotly交互式时序图阈值高亮及手动标注问题咨询

在Plotly中实现时序图阈值高亮与手动标注

问题原因

ggplot转换为ggplotly时,geom_rect基于单数据点生成的矩形在交互式图中无法正常渲染,尤其是时间轴上的偏移计算(DateTime-450)不被Plotly正确解析。改用Plotly原生API可直接控制图形元素,解决该问题。

实现步骤与代码示例

1. 预处理数据:识别连续高亮区间

先将离散的阈值超标点转换为连续时间区间,避免重复添加矩形:

library(plotly)
library(dplyr)

# 生成原始数据(沿用原逻辑)
start_time <- as.POSIXct("2024-05-01 00:00:00")
end_time <- as.POSIXct("2024-05-02 00:00:00")
time_seq <- seq(from = start_time, to = end_time, by = "15 min")
variable1 <- rnorm(length(time_seq), mean = 25, sd = 5)
variable2 <- rnorm(length(time_seq), mean = 350, sd = 20)
df <- data.frame(DateTime = time_seq, Variable1 = variable1, Variable2 = variable2)

# 处理Variable1的高亮区间(>28.3)
df$var1_high <- df$Variable1 > 28.3
df$group_var1 <- cumsum(c(1, diff(df$var1_high) != 0))
var1_intervals <- df %>%
  filter(var1_high) %>%
  group_by(group_var1) %>%
  summarise(
    x_start = min(DateTime) - 450,
    x_end = max(DateTime) + 450,
    y_min = -Inf,
    y_max = Inf,
    mid_time = mean(as.numeric(DateTime)),
    mid_y = max(Variable1) + 1
  ) %>%
  ungroup()

# 处理Variable2的高亮区间(335<x<390)
df$var2_high <- df$Variable2 > 335 & df$Variable2 < 390
df$group_var2 <- cumsum(c(1, diff(df$var2_high) != 0))
var2_intervals <- df %>%
  filter(var2_high) %>%
  group_by(group_var2) %>%
  summarise(
    x_start = min(DateTime) - 450,
    x_end = max(DateTime) + 450,
    y_min = -Inf,
    y_max = Inf,
    mid_time = mean(as.numeric(DateTime)),
    mid_y = max(Variable2) + 5
  ) %>%
  ungroup()

2. 绘制Variable1的交互式图(高亮+标注)

# 创建Variable1的Plotly图
p1 <- plot_ly(df, x = ~DateTime, y = ~Variable1, type = 'scatter', mode = 'lines', color = I("blue")) %>%
  # 添加高亮矩形
  add_shapes(
    lapply(1:nrow(var1_intervals), function(i) {
      list(
        type = "rect",
        x0 = var1_intervals$x_start[i],
        x1 = var1_intervals$x_end[i],
        y0 = var1_intervals$y_min[i],
        y1 = var1_intervals$y_max[i],
        fillcolor = "lightblue",
        opacity = 0.3,
        line = list(width = 0)
      )
    })
  ) %>%
  # 添加"Pos"标注(可按需修改为"Neg")
  add_annotations(
    x = as.POSIXct(var1_intervals$mid_time, origin = "1970-01-01"),
    y = var1_intervals$mid_y,
    text = "Pos",
    showarrow = FALSE,
    font = list(size = 12, color = "darkblue")
  ) %>%
  layout(
    xaxis = list(title = "Time"),
    yaxis = list(title = "Variable 1"),
    showlegend = FALSE
  )

3. 绘制Variable2的交互式图(高亮+标注)

# 创建Variable2的Plotly图
p2 <- plot_ly(df, x = ~DateTime, y = ~Variable2, type = 'scatter', mode = 'lines', color = I("red")) %>%
  add_shapes(
    lapply(1:nrow(var2_intervals), function(i) {
      list(
        type = "rect",
        x0 = var2_intervals$x_start[i],
        x1 = var2_intervals$x_end[i],
        y0 = var2_intervals$y_min[i],
        y1 = var2_intervals$y_max[i],
        fillcolor = "lightpink",
        opacity = 0.3,
        line = list(width = 0)
      )
    })
  ) %>%
  add_annotations(
    x = as.POSIXct(var2_intervals$mid_time, origin = "1970-01-01"),
    y = var2_intervals$mid_y,
    text = "Pos",
    showarrow = FALSE,
    font = list(size = 12, color = "darkred")
  ) %>%
  layout(
    xaxis = list(title = "Time"),
    yaxis = list(title = "Variable 2"),
    showlegend = FALSE
  )

4. 组合两个垂直排列的交互式图

# 组合图并对齐x轴
combined_plot <- subplot(p1, p2, nrows = 2, shareX = TRUE, titleY = TRUE)
combined_plot

关键说明

  • add_shapes是Plotly原生图形元素添加函数,直接控制矩形起止时间,规避ggplot转换的兼容性问题。
  • 先分组识别连续高亮区间,减少矩形数量,提升交互性能。
  • add_annotations可精确控制标注位置,根据需求修改text参数为"Pos"或"Neg"。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 19:31:06