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

如何在Plotly(R)的x unified hovermode中修改日期表头格式

解决Plotly(R) x-unified悬停模式下表头日期格式修改问题

针对你需要修改悬停表头日期格式(不改动x轴刻度)的需求,以下提供两种对应你目标格式的解决方案:

方案1:改为「1 jan (week 01)」格式

方法A:利用x轴hoverformat参数(快速实现)

hoverformat是Plotly专门控制悬停时x轴值显示格式的参数,不会影响x轴刻度。你可以直接在layout的xaxis配置中添加该参数:

plot1 %>% 
  layout(
    font = list(size = 10),
    xaxis = list(title = list(text = '<b>Date<b>', font = list(size = 12))
                 , fixedrange = T, showgrid = FALSE, ticks = 'inside', type = 'date'
                 , hoverformat = "%d %b (week %V)"  # %V为ISO标准周数,换%W则按周一为周起始,%U按周日为周起始
                 ),
    yaxis = list(title = list(text = '<b>Number of value1<b>', font = list(size = 12, color = '#E64B35FF'))
                 , fixedrange = T
                 , rangemode = 'tozero', showgrid = FALSE, showline = T, ticks = 'inside'),
    yaxis2 = list(overlaying = 'y', side = 'right', fixedrange = T, rangemode = 'tozero', showgrid = FALSE, showline = T, ticks = 'inside'
                  , title = list(text = '<b>Number of value2<b>', font = list(size = 12, color = '#4DBBD5FF'))),
    margin = list(t = 50, r = 50),
    hovermode = "x unified"
  )

注意:2022-01-01按ISO标准属于2021年第52周,若你需要从每年1月1日开始算第1周,可使用方法B自定义周数。

方法B:自定义周数+JS修改表头(精准控制)

  1. 先在数据中计算自定义周数并生成目标文本:
library(lubridate)
# 计算从当年1月1日开始的周数
df_data1$custom_week <- as.integer(difftime(df_data1$date_input, floor_date(df_data1$date_input, "year"), units = "weeks")) + 1
df_data1$hover_date <- paste0(format(df_data1$date_input, "%d %b"), " (week ", sprintf("%02d", df_data1$custom_week), ")")
# 同步到第二个数据框
df_data2$hover_date <- df_data1$hover_date
  1. 使用htmlwidgets添加JS代码替换悬停表头:
library(htmlwidgets)

plot1 %>% 
  layout(
    font = list(size = 10),
    xaxis = list(title = list(text = '<b>Date<b>', font = list(size = 12))
                 , fixedrange = T, showgrid = FALSE, ticks = 'inside', type = 'date'),
    yaxis = list(title = list(text = '<b>Number of value1<b>', font = list(size = 12, color = '#E64B35FF'))
                 , fixedrange = T
                 , rangemode = 'tozero', showgrid = FALSE, showline = T, ticks = 'inside'),
    yaxis2 = list(overlaying = 'y', side = 'right', fixedrange = T, rangemode = 'tozero', showgrid = FALSE, showline = T, ticks = 'inside'
                  , title = list(text = '<b>Number of value2<b>', font = list(size = 12, color = '#4DBBD5FF'))),
    margin = list(t = 50, r = 50),
    hovermode = "x unified"
  ) %>%
  onRender("
    function(el, x) {
      el.on('plotly_hover', function(d) {
        const targetText = d.points[0].data.hover_date[d.points[0].pointIndex];
        const hoverLabel = el.querySelector('.hovertext .x-value');
        if (hoverLabel) hoverLabel.textContent = targetText;
      });
    }
  ")

方案2:改为「1 jan - 8 jan 22」格式(周范围)

  1. 先计算每周结束日期并生成范围文本:
# 计算周结束日期(当前日期+6天,匹配每周7天的周期)
df_data1$end_date <- df_data1$date_input + 6
df_data1$hover_range <- paste0(format(df_data1$date_input, "%d %b"), " - ", format(df_data1$end_date, "%d %y"))
# 同步到第二个数据框
df_data2$hover_range <- df_data1$hover_range
  1. 同样用JS替换悬停表头:
plot1 %>% 
  layout(
    font = list(size = 10),
    xaxis = list(title = list(text = '<b>Date<b>', font = list(size = 12))
                 , fixedrange = T, showgrid = FALSE, ticks = 'inside', type = 'date'),
    yaxis = list(title = list(text = '<b>Number of value1<b>', font = list(size = 12, color = '#E64B35FF'))
                 , fixedrange = T
                 , rangemode = 'tozero', showgrid = FALSE, showline = T, ticks = 'inside'),
    yaxis2 = list(overlaying = 'y', side = 'right', fixedrange = T, rangemode = 'tozero', showgrid = FALSE, showline = T, ticks = 'inside'
                  , title = list(text = '<b>Number of value2<b>', font = list(size = 12, color = '#4DBBD5FF'))),
    margin = list(t = 50, r = 50),
    hovermode = "x unified"
  ) %>%
  onRender("
    function(el, x) {
      el.on('plotly_hover', function(d) {
        const targetText = d.points[0].data.hover_range[d.points[0].pointIndex];
        const hoverLabel = el.querySelector('.hovertext .x-value');
        if (hoverLabel) hoverLabel.textContent = targetText;
      });
    }
  ")

为什么tickprefix不适用?

tickprefix是用来修改x轴刻度的前缀,会直接改变轴上显示的刻度文本,无法实现仅修改悬停表头的需求,因此需要使用上述针对悬停文本的专用方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:57:35