%H:%M
,即使花费时间超过一天的时间。
原始数据集持续时间在几分钟之内,我将其转换为60.小时。 我目前的结果。
reprex
用Rreprexv2.1.1于2025-02-18创建 任何建议?
一个实现所需结果的选择是手动移动标签的位置,而不是依靠
set.seed(123)
library(tidyverse)
library(ggplot2)
library(zoo)
#>
#> Attaching package: 'zoo'
#> The following objects are masked from 'package:base':
#>
#> as.Date, as.Date.numeric
library(ggnewscale)
dat <- tibble(
user = c("user1", "user1", "user1", "user2", "user2", "user2", "user1", "user1", "user1", "user2", "user2", "user2"),
type = c("tv", "tv", "tv", "tv", "tv", "tv", "movie", "movie", "movie", "movie", "movie", "movie"),
yearmonth = as.yearmon(rep_len(seq.Date(as.Date("2024-12-01"), as.Date("2025-02-01"), "month"), 12)),
cumulative_minutes = sample(200:900, 12, replace = TRUE)
)
diff_dat <- dat |>
pivot_wider(
names_from = user,
values_from = cumulative_minutes
) |>
group_by(type, yearmonth) %>%
mutate(
diff = user1 - user2,
max_y = max(user1, user2),
min_y = min(user1, user2),
pos_y = (max_y - min_y) / 2 + min_y,
u1_higher = user1 > user2,
)
ggplot() +
scale_x_yearmon(breaks = dat$yearmonth, labels = rev(dat$yearmonth)) +
geom_col(
data = filter(diff_dat, type == "movie"),
aes(x = rev(yearmonth), y = max_y / 60),
fill = ifelse(filter(diff_dat, type == "movie")$u1_higher, "#C7E9C0", "#FCBBA1"),
) +
geom_col(
data = filter(dat, type == "movie"),
aes(x = rev(yearmonth),y = cumulative_minutes / 60, group = rev(user), fill = user),
position = "dodge",
) +
geom_text(
data = filter(diff_dat, type == "movie"),
aes(x = rev(yearmonth), y = pos_y / 60, label = round(diff/60, digits = 1)),
position = position_dodge(0.1),
vjust = ifelse(filter(diff_dat, type == "movie")$u1_higher, +2, -2),
size = 3,
) +
scale_fill_brewer(palette = "Dark2", guide = guide_legend("Movies", order = 1)) +
new_scale_fill() +
geom_col(
data = filter(diff_dat, type == "tv"),
aes(x = rev(yearmonth), y = - (max_y / 60)),
fill = ifelse(filter(diff_dat, type == "tv")$u1_higher, "#C7E9C0", "#FCBBA1"),
) +
geom_col(
data = filter(dat, type == "tv"),
aes(x = rev(yearmonth), y = - (cumulative_minutes / 60), group = rev(user), fill = user),
position = "dodge"
) +
geom_text(
data = filter(diff_dat, type == "tv"),
aes(x = rev(yearmonth), y = - (pos_y / 60), label = round(diff/60, digits = 1)),
position = position_dodge(0.1),
vjust = ifelse(filter(diff_dat, type == "tv")$u1_higher, +2, -2),
size = 3,
) +
scale_fill_brewer(palette = "Set1", guide = guide_legend("TV", order = 2)) +
scale_y_continuous(labels = abs) +
ylab("Hours") +
xlab("Month") +
theme_light() +
coord_flip()
#> Warning: `position_dodge()` requires non-overlapping x intervals.
#> `position_dodge()` requires non-overlapping x intervals.
。对于标签,我使用一个小的辅助函数来创建所需的格式:
position_dodge