首页 > 解决方案 > 使用 POSIXct 和夏令时绘制条形图

问题描述

我想在 x 轴上绘制带有时间戳的条形图时间序列。我的问题是Octobre 的夏令时,因为 02:00 有 2 个时间戳,一个带有CEST时区,一个带有CET

plotly 条形图叠加了这些值,当您将鼠标悬停在条形图上时,很难发现并且看起来像错误,因为您会发现该值与 y 轴不对应。

如何在不更改“数组”和定义的情况下并排显示这 2 个条形tickmodetickvals/ticktext

library(plotly)

df <- structure(list(value = round(runif(46, 20, 26), 3), 
                     timestamp = structure(c(1603576800, 1603584000, 1603587600, 1603591200, 1603594800, 1603598400, 
                                             1603602000, 1603605600, 1603609200, 1603612800, 1603616400, 1603620000,
                                             1603623600, 1603627200, 1603630800, 1603634400, 1603638000, 1603641600,
                                             1603645200, 1603648800, 1603652400, 1603656000, 1603659600, 1603576800,
                                             1603584000, 1603587600, 1603591200, 1603594800, 1603598400, 1603602000, 
                                             1603605600, 1603609200, 1603612800, 1603616400, 1603620000, 1603623600,
                                             1603627200, 1603630800, 1603634400, 1603638000, 1603641600, 1603645200,
                                             1603648800, 1603652400, 1603656000, 1603659600), 
                                           class = c("POSIXct", "POSIXt"), tzone = "Europe/Berlin"), 
                     col = c(rep("#FFBA00", 23), rep("#B9CC2E", 23)), 
                     name = c(rep("Grp1", 23), rep("Grp2", 23))), 
                row.names = 1:46, class = "data.frame")

plot_ly(data = df, text = "text") %>%
  add_trace(x = ~timestamp, y = ~value, type = "bar",
            marker = list(color = ~col),
            text = ~sprintf("Time: %s<br>Value: %s", timestamp, value),
            hoverinfo = "text",
            name = ~name) %>% 
  plotly::layout(xaxis = list(title = 'Time', type = "date"),
                 barmode = 'group')

标签: rplotlydstr-plotly

解决方案


将我的评论总结为未来读者的答案:

plotly目前不支持原生显示夏令时:

更改我们的内部日期线性化以使用 UTC 而不是本地毫秒。现在,Plotly 图表上的每一天都是 24 小时长,没有昼夜交替。

来源:https ://github.com/plotly/plotly.js/pull/1194#issue-95087563

因此,我知道解决此问题的唯一可能性是在 plotly 的函数中使用tickvalsand参数(@SeGa 不需要,这是合理的,因为我们将重复刻度标签。不过,也许以下内容对其他人有帮助)。ticktextlayout

library(plotly)

DF <- structure(list(value = round(runif(46, 20, 26), 3), 
                     timestamp = structure(c(1603576800, 1603584000, 1603587600, 1603591200, 1603594800, 1603598400, 
                                             1603602000, 1603605600, 1603609200, 1603612800, 1603616400, 1603620000,
                                             1603623600, 1603627200, 1603630800, 1603634400, 1603638000, 1603641600,
                                             1603645200, 1603648800, 1603652400, 1603656000, 1603659600, 1603576800,
                                             1603584000, 1603587600, 1603591200, 1603594800, 1603598400, 1603602000, 
                                             1603605600, 1603609200, 1603612800, 1603616400, 1603620000, 1603623600,
                                             1603627200, 1603630800, 1603634400, 1603638000, 1603641600, 1603645200,
                                             1603648800, 1603652400, 1603656000, 1603659600), 
                                           class = c("POSIXct", "POSIXt"), tzone = "Europe/Berlin"), 
                     col = c(rep("#FFBA00", 23), rep("#B9CC2E", 23)), 
                     name = c(rep("Grp1", 23), rep("Grp2", 23))), 
                row.names = 1:46, class = "data.frame")

# DF$timestamp_utc <- DF$timestamp
# attr(DF$timestamp_utc, "tzone") <- "UTC" 

plot_ly(data = DF, text = "text") %>%
  add_trace(x = ~as.numeric(timestamp), y = ~value, type = "bar",
            marker = list(color = ~col),
            text = ~sprintf("Time: %s<br>Value: %s", timestamp, value),
            hoverinfo = "text",
            name = ~name) %>% 
  plotly::layout(xaxis = list(title = 'Time',
                              ticktext = ~timestamp, 
                              tickvals = ~as.numeric(timestamp),
                              tickmode = "array"),
                 barmode = 'group')

结果


次要编辑:如果我们想不费力气地减少刻度标签的数量,我们可以prettyticktextand中使用tickvals

ticktext = ~pretty(timestamp), 
tickvals = ~as.numeric(pretty(timestamp))

漂亮的

相关文档:在 R 中格式化刻度


推荐阅读