【问题标题】:Bar Chart with variable width of bars条形可变宽度的条形图
【发布时间】:2018-02-06 17:27:16
【问题描述】:

我正在尝试创建某种类型的条形图/直方图,其中条形的宽度取决于两列。 s1 = 开始时间 s2 = 停止时间。我的 x 轴是从午夜到午夜的 24 小时。因此,如果一行为 s1 = 12:00 AM s2 = 1:45 AM 那么条形图将从上午 12:00 到 1:45 AM,如果下一行是 s1 = 2:00 AM s2 = 2:30上午,该条将比第一个更窄,因为与第一个条中的 1.75 小时相比,它仅持续 30 分钟。然后高度取决于第三列值,它也是连续数据。如果有另一种可视化,我也对此持开放态度。时间之间不应有重叠,但如果条形图是透明的/显示有重叠的图案会很有帮助。

下面是与我使用的类似的少量数据

             s1     |        s2         |  Value
 1/1/2018 12:00 AM  | 1/1/2018 1:45 AM  |  10.2
 1/1/2018 2:00 AM   | 1/1/20182:30 AM   |  3.1

【问题讨论】:

  • 你想如何处理重叠条?
  • erocoar 我刚刚更新了这个问题。谢谢。

标签: r width bar-chart


【解决方案1】:

应该这样做:

dat <- data.frame(start = c("1/1/2018 12:00 AM", "1/1/2018 2:00 AM"),
         stop = c("1/1/2018 1:45 AM", "1/1/2018 2:30 AM"),
         value = c(10.2, 3.1))

dat$start <- strptime(dat$start, "%d/%m/%Y %I:%M %p")
dat$stop <- strptime(dat$stop, "%d/%m/%Y %I:%M %p")

lower <- as.POSIXct(strftime(min(dat$start),"%Y-%m-%d"))
upper <- as.POSIXct(strftime(as.Date(max(dat$start))+1,"%Y-%m-%d"))-1
limits = c(lower,upper)

ggplot(dat) + 
  geom_rect(aes(xmin = dat$start, xmax = dat$stop,
                ymin = 0, ymax = dat$value), alpha = 0.8, color = "black") +
  scale_x_datetime(
    date_breaks = "2 hour", 
    date_minor_breaks = "1 hour",
    labels = date_format("%H:%M", tz = "CET"),
    limits = limits)

如果您没有重叠和/或 y 描述类别,您可以考虑 ggalt 包中的 geom_dumbbell。数据量大,也可以考虑geom_horizon(同包)

【讨论】:

  • 为什么不直接使用允许显式宽度参数的geom_bar(... aes(width=...
  • 我认为width参数不能为每个条单独指定?
  • 我不确定如何指定宽度,尤其是在时间尺度上@smci,而geom_bar 只是调用geom_rect 反正
【解决方案2】:

我认为这应该可行!方法是重塑数据,以便每次有一个值,包括在两次之间添加零值。然后您可以使用geom_step 进行绘图。这本身并不是真正的“条形图”,因为它们应该用于分类数据。您的数据看起来更像是在特定位置没有值的连续时间序列,因此我们只需为该序列构建正确的数据。

我认为添加权限行的步骤比他们应该做的更复杂 - 如果有人有改进建议请随意!

    library(tidyverse)
tbl <- tribble(
  ~s1, ~s2, ~value,
  "1/1/2018 12:00 AM", "1/1/2018 1:45 AM", 10.2,
  "1/1/2018 2:00 AM", "1/1/2018 2:30 AM", 3.1
) %>%
  mutate_at(vars(s1, s2), lubridate::dmy_hm) %>%
  gather("s", "datetime", s1, s2) %>%
  arrange(datetime)
tbl_1 <- tbl %>% bind_cols(id = group_indices(tbl, value))

tbl_2 <- tbl_1 %>%
  group_by(id) %>%
  summarise(datetime = last(datetime)) %>%
  mutate(s = "s4", value = 0) %>%
  bind_rows(tbl_1, .)
full_tbl <- tbl_2 %>%
  group_by(id) %>%
  summarise(datetime = first(datetime)) %>%
  mutate(s = "s0", value = 0) %>%
  bind_rows(., tbl_2) %>%
  arrange(datetime, s)

print(full_tbl)
#> # A tibble: 8 x 4
#>      id datetime            s     value
#>   <int> <dttm>              <chr> <dbl>
#> 1     2 2018-01-01 00:00:00 s0     0   
#> 2     2 2018-01-01 00:00:00 s1    10.2 
#> 3     2 2018-01-01 01:45:00 s2    10.2 
#> 4     2 2018-01-01 01:45:00 s4     0   
#> 5     1 2018-01-01 02:00:00 s0     0   
#> 6     1 2018-01-01 02:00:00 s1     3.10
#> 7     1 2018-01-01 02:30:00 s2     3.10
#> 8     1 2018-01-01 02:30:00 s4     0

ggplot(data = full_tbl) + geom_step(aes(x = datetime, y = value))

猜你喜欢
  • 2020-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-17
  • 2011-10-05
相关资源
最近更新 更多