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

如何垂直合并timevis时间线图与散点图并完美对齐X轴(时间轴)

如何垂直合并timevis时间线图与散点图并完美对齐X轴(时间轴)

嘿,我懂你想把timevis时间线和散点图上下叠放、还得让X轴严丝合缝对齐的需求,之前标签变形的问题确实挺闹心的。我给你整理了一套可行的方案,核心是让两个图表共享完全一致的时间范围,同时调整布局和标签样式来避免变形:

关键思路

  • 时间轴同步:让散点图的X轴范围和timevis实时保持一致,不管是初始加载还是用户拖动缩放时间线,两者的时间轴都完全对齐
  • 标签防变形:调整散点图的X轴标签角度和样式,避免重叠扭曲
  • 布局一致性:用Shiny的垂直布局保证两个图表宽度完全匹配

完整可运行代码

library(shiny)
library(timevis)
library(ggplot2)

# 补全你的数据(假设dataLog的完整结构如下)
psa <- data.frame(
  date = as.POSIXct(c("2019-12-18", "2020-01-15", "2020-02-19", "2020-04-02", "2020-06-25", "2020-06-26", "2020-07-16", "2020-08-13", "2020-09-17", "2020-10-15")),
  psa = c(251.8, 65.5, 7.4, 9.4, 13.2, 13.20, 18.4, 15.3, 87.6, 90)
)

dataLog <- data.frame(
  content = c("Prostate Cancer", "Lymph nodes & Bone", "Bicalutamide", 
              "Leuprolide", "Abiraterone & Prednisone", "Zometa", "Enzalutamide"),
  start = as.POSIXct(c("2019-12-18", "2020-01-01", "2020-01-15", 
                       "2020-02-19", "2020-04-02", "2020-06-25", "2020-08-13")),
  end = rep(NA, 7),
  group = c("Diagnosis", "Metastasis", "Medication", "Medication", "Medication", "Medication", "Medication")
)

ui <- fluidPage(
  # 垂直布局保证两个图表宽度一致
  verticalLayout(
    # timevis时间线,设置id以便获取窗口范围
    timevisOutput("timeline", height = "200px"),
    # 散点图,高度可按需调整
    plotOutput("scatter_plot", height = "300px")
  )
)

server <- function(input, output, session) {
  # 渲染timevis时间线
  output$timeline <- renderTimevis({
    timevis(
      data = dataLog,
      groups = data.frame(id = c("Diagnosis", "Metastasis", "Medication"), content = c("诊断", "转移", "药物")),
      options = list(editable = FALSE, showCurrentTime = FALSE)
    )
  })
  
  # 动态获取时间范围:优先用timevis当前窗口,初始用psa的日期范围
  time_range <- reactive({
    if (!is.null(input$timeline_window)) {
      # 从timevis的窗口输入提取当前时间范围
      c(as.POSIXct(input$timeline_window[1], origin = "1970-01-01"),
        as.POSIXct(input$timeline_window[2], origin = "1970-01-01"))
    } else {
      # 初始范围用psa数据的最小和最大日期
      range(psa$date)
    }
  })
  
  # 渲染散点图,同步时间范围并调整标签样式
  output$scatter_plot <- renderPlot({
    ggplot(psa, aes(x = date, y = psa)) +
      geom_point(size = 3, color = "#2c3e50") +
      geom_line(color = "#3498db") +
      # 同步X轴范围和timevis完全一致
      xlim(time_range()) +
      labs(x = "日期", y = "PSA值") +
      theme_minimal() +
      # 调整X轴标签,旋转45度避免重叠变形
      theme(
        axis.text.x = element_text(angle = 45, hjust = 1, size = 10),
        axis.title.x = element_text(size = 12),
        axis.title.y = element_text(size = 12)
      )
  })
}

shinyApp(ui, server)

方案说明

  1. 实时对齐时间轴:通过input$timeline_window获取timevis当前显示的时间范围,实时同步到散点图的xlim()中,不管你怎么拖动缩放时间线,散点图的X轴都会完美匹配
  2. 解决标签变形:用theme(axis.text.x = element_text(angle = 45, hjust = 1))把X轴标签旋转45度,同时调整字体大小,彻底解决标签重叠扭曲的问题
  3. 布局统一:用verticalLayout让两个图表默认占满页面宽度,确保X轴的长度完全一致

你可以直接运行这段代码,要是需要调整图表高度或者样式,直接修改height参数和ggplot的theme就行~

备注:内容来源于stack exchange,提问作者user3781528

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 13:44:29