如何在vistime中为同一时间条按百分比设置不同分段颜色
R vistime包实现时间条按比例分段配色方案
vistime 原生不支持单条时间块内部分段填充不同颜色,可通过拆分时间块为连续子段的方式实现目标效果:将需要分色的单条时间按占比拆成多个首尾完全衔接的子时间条目,给每个子条目单独设置填充色,绘图后视觉上和单条分色无差异,不会出现断缝。
实现步骤
- 先将数据集中的起止时间统一转为
Date格式,方便按比例计算时间分界点 - 按自定义的分色占比,拆分原时间条目为多个子条目,保持分组、标签属性和原条目一致,为不同分段指定对应颜色
- 用拆分后的数据集直接调用vistime绘图即可
可复现代码(基于提供的测试数据)
示例实现Washington任期条60%填充红色、剩余40%填充蓝色的效果:
library(lubridate) library(vistime) # 原测试数据集,先将起止时间转为Date类型 pres <- data.frame( Position = rep(c("President", "Vice"), each = 3), Name = c("Washington", rep(c("Adams", "Jefferson"), 2), "Burr"), start = as.Date(c("1789-03-29", "1797-02-03", "1801-02-03")), end = as.Date(c("1797-02-03", "1801-02-03", "1809-02-03")), fontcolor = c("black", "white", "black") ) # 自定义分色规则:可按需追加多条规则,支持任意段数、任意占比 split_config <- data.frame( target_entry = "Washington", pct = c(0.6, 0.4), fill_color = c("red", "blue") ) # 按规则拆分数据集 pres_processed <- do.call(rbind, lapply(1:nrow(pres), function(row_idx){ row_data <- pres[row_idx, ] # 命中分色规则的条目执行拆分 if (row_data$Name %in% split_config$target_entry) { config <- split_config[split_config$target_entry == row_data$Name, ] total_duration <- as.numeric(difftime(row_data$end, row_data$start, units = "days")) seg_breakpoints <- cumsum(c(0, config$pct * total_duration)) seg_data <- data.frame( Position = row_data$Position, Name = row_data$Name, start = row_data$start + lubridate::days(seg_breakpoints[-length(seg_breakpoints)]), end = row_data$start + lubridate::days(seg_breakpoints[-1]), color = config$fill_color, fontcolor = row_data$fontcolor ) return(seg_data) } # 未命中规则的条目保留原配色 row_data$color <- c('#cbb69d', '#603913', '#c69c6e')[row_idx] return(row_data) })) # 生成最终图表 vistime(pres_processed, events = "Position", groups = "Name", title = "Presidents of the USA")
关键细节:拆分时必须保证前一个子段的结束时间和后一个子段的开始时间完全相等,否则绘图时会出现缝隙。如果需要给其他时间条加分段色,直接在
split_config中追加对应规则即可,支持单条拆分为3段及以上的多色效果。
内容的提问来源于stack exchange,提问作者renit Anthony
相关产品推荐
相关产品推荐

