如何在ggplot与plotly时间直方图中设置MM:SS格式悬停文本
问题描述
需要在R中使用ggplot2和plotly绘制时间直方图,时间数据以秒为单位存储,核心需求:
- 坐标轴标签显示为MM:SS格式(支持带小数的秒数)
- 悬停提示文本显示为MM:SS格式
当前存在两个问题:
- 坐标轴仅显示2个标签,无法展示更多刻度
- 悬停提示文本无法正常显示
当前代码、自定义函数及示例数据如下:
# 当前代码 p2 <- df %>% mutate(time_formatted = gsub("^0+", "", sprintf("%02d:%05.2f", floor(time_seconds/60), time_seconds %% 60))) %>% mutate(bucketed_time = floor(time_seconds)) %>% mutate(hover_text = paste0('Time: ', custom_labels(time_seconds))) %>% ggplot(aes(x = time_seconds)) + geom_histogram(fill = mako_palette[50], binwidth = 1, position = 'dodge') + labs(title = 'Times Histogram')) + scale_y_continuous(name = 'Count') + scale_x_reverse(name = 'Time', labels = custom_labels) + theme_minimal() ggplotly(p2, dynamicTicks = FALSE, tooltip = 'text', originalData = TRUE, hoverinfo = 'text', text = ~hover_text) %>% config(displayModeBar = FALSE)
# 自定义函数 custom_labels_bucketed <- function(x) { minutes <- floor(x / 60) seconds <- x %% 60 sprintf("%d:%02d", minutes, seconds) }
# 示例数据 df <- structure(list(time_seconds = c(60.46, 50.84, 64.54, 54.1, 59.21, 73.45, 40.39, 38.31, 69.11, 74.17), name = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J")), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"))
解决方案
问题根源
- 自定义函数名称不匹配:代码中调用
custom_labels,但实际定义的函数是custom_labels_bucketed,导致标签生成失败 - 坐标轴刻度自动选择:ggplot默认只生成少量刻度,需手动指定合理的刻度间隔
- 悬停文本未绑定图层:
geom_histogram的aes中未传入text参数,plotly无法读取悬停文本
修正后的完整代码
# 加载依赖包 library(tidyverse) library(plotly) # 统一自定义时间格式化函数(支持MM:SS.ss格式) custom_labels <- function(x) { minutes <- floor(x / 60) seconds <- x %% 60 sprintf("%d:%05.2f", minutes, seconds) } # 数据预处理 + 绘制ggplot p2 <- df %>% mutate(hover_text = paste0('Time: ', custom_labels(time_seconds))) %>% ggplot(aes(x = time_seconds, text = hover_text)) + # 将悬停文本绑定到图层 geom_histogram(fill = mako_palette[50], binwidth = 1, position = 'dodge') + labs(title = 'Times Histogram', y = 'Count', x = 'Time') + scale_y_continuous(name = 'Count') + scale_x_reverse( name = 'Time', labels = custom_labels, # 手动设置刻度:从数据最小秒数到最大秒数,每5秒一个刻度 breaks = seq(floor(min(df$time_seconds)), ceiling(max(df$time_seconds)), by = 5) ) + theme_minimal() # 转换为plotly交互图 ggplotly(p2, tooltip = 'text') %>% config(displayModeBar = FALSE)
关键修改说明
- 统一函数名称为
custom_labels,确保调用和定义一致 - 在
ggplot(aes())中添加text = hover_text,让plotly能读取悬停文本 - 通过
scale_x_reverse的breaks参数生成间隔为5秒的刻度,解决标签过少问题 - 简化
ggplotly参数,仅保留必要的tooltip = 'text'即可正常显示悬停提示
内容的提问来源于stack exchange,提问作者user276238
相关产品推荐
相关产品推荐

