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

如何在ggplot与plotly时间直方图中设置MM:SS格式悬停文本

问题描述

需要在R中使用ggplot2和plotly绘制时间直方图,时间数据以秒为单位存储,核心需求:

  • 坐标轴标签显示为MM:SS格式(支持带小数的秒数)
  • 悬停提示文本显示为MM:SS格式

当前存在两个问题:

  1. 坐标轴仅显示2个标签,无法展示更多刻度
  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"))

解决方案

问题根源

  1. 自定义函数名称不匹配:代码中调用custom_labels,但实际定义的函数是custom_labels_bucketed,导致标签生成失败
  2. 坐标轴刻度自动选择:ggplot默认只生成少量刻度,需手动指定合理的刻度间隔
  3. 悬停文本未绑定图层: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)

关键修改说明

  1. 统一函数名称为custom_labels,确保调用和定义一致
  2. 在ggplot(aes())中添加text = hover_text,让plotly能读取悬停文本
  3. 通过scale_x_reverse的breaks参数生成间隔为5秒的刻度,解决标签过少问题
  4. 简化ggplotly参数,仅保留必要的tooltip = 'text'即可正常显示悬停提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:15:29