如何在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修改表头(精准控制)
- 先在数据中计算自定义周数并生成目标文本:
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
- 使用
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」格式(周范围)
- 先计算每周结束日期并生成范围文本:
# 计算周结束日期(当前日期+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
- 同样用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
相关产品推荐
相关产品推荐

