如何在ggplot的geom_segment对话注视方向图中视觉分隔相邻线段?
问题描述
我用geom_segment绘制对话中的注视方向图,但线段颜色相近时,很难区分一段线段的结束和另一段的起始。请问怎么插入分割类视觉元素(比如矩形或竖线),让不同线段的分隔效果更直观?
原绘图代码
library(ggnewscale) ggplot(data = df1, aes(x = start, xend = end, y = MM_by, yend = MM_by, color = MM_annotation)) + geom_segment(size = 4) + scale_y_discrete(name = NULL, limits = rev) + facet_wrap(~ Utterance, scales = "free_x", ncol = 1) + scale_colour_manual(values = c("*" = "white", "A" = "yellow", "B" = "lawngreen", "C" = "cyan"), # 重命名图例标题: name = "Gaze to")
数据集
df1 <- structure(list(Line = c(569L, 569L, 569L, 569L, 569L, 569L, 569L, 569L, 569L, 569L, 570L, 570L, 570L, 570L, 571L, 571L, 571L, 573L, 573L, 573L, 573L, 573L, 573L), Speaker = c("ID01.C", "ID01.C", "ID01.C", "ID01.C", "ID01.C", "ID01.C", "ID01.C", "ID01.C", "ID01.C", "ID01.C", NA, NA, NA, NA, "ID01.C", "ID01.C", "ID01.C", "ID01.A", "ID01.A", "ID01.A", "ID01.A", "ID01.A", "ID01.A"), Timestamp = c("00:12:02.300 - 00:12:04.113", "00:12:02.300 - 00:12:04.113", "00:12:02.300 - 00:12:04.113", "00:12:02.300 - 00:12:04.113", "00:12:02.300 - 00:12:04.113", "00:12:02.300 - 00:12:04.113", "00:12:02.300 - 00:12:04.113", "00:12:02.300 - 00:12:04.113", "00:12:02.300 - 00:12:04.113", "00:12:02.300 - 00:12:04.113", "00:12:04.113 - 00:12:04.667", "00:12:04.113 - 00:12:04.667", "00:12:04.113 - 00:12:04.667", "00:12:04.113 - 00:12:04.667", "00:12:04.667 - 00:12:05.737", "00:12:04.667 - 00:12:05.737", "00:12:04.667 - 00:12:05.737", "00:12:05.777 - 00:12:08.395", "00:12:05.777 - 00:12:08.395", "00:12:05.777 - 00:12:08.395", "00:12:05.777 - 00:12:08.395", "00:12:05.777 - 00:12:08.395", "00:12:05.777 - 00:12:08.395"), Utterance = c("[what's] a !mountain! for you:", "[what's] a !mountain! for you:", "[what's] a !mountain! for you:", "[what's] a !mountain! for you:", "[what's] a !mountain! for you:", "[what's] a !mountain! for you:", "[what's] a !mountain! for you:", "[what's] a !mountain! for you:", "[what's] a !mountain! for you:", "[what's] a !mountain! for you:", "(0.554)", "(0.554)", "(0.554)", "(0.554)", "((v: laughs))=", "((v: laughs))=", "((v: laughs))=", "=I don't know the (Schauinsland) is a small mount[ain]", "=I don't know the (Schauinsland) is a small mount[ain]", "=I don't know the (Schauinsland) is a small mount[ain]", "=I don't know the (Schauinsland) is a small mount[ain]", "=I don't know the (Schauinsland) is a small mount[ain]", "=I don't know the (Schauinsland) is a small mount[ain]"), File = c("F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01", "F01"), Starttime_ms = c(722300L, 722300L, 722300L, 722300L, 722300L, 722300L, 722300L, 722300L, 722300L, 722300L, 724113L, 724113L, 724113L, 724113L, 724667L, 724667L, 724667L, 725777L, 725777L, 725777L, 725777L, 725777L, 725777L), Endtime_ms = c(724113, 724113, 724113, 724113, 724113, 724113, 724113, 724113, 724113, 724113, 724667, 724667, 724667, 724667, 725737, 725737, 725737, 728395, 728395, 728395, 728395, 728395, 728395), UttEnd = c(1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 2367, 2367, 2367, 2367, 3437, 3437, 3437, 6055, 6055, 6055, 6055, 6055, 6055), UttStart = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1813, 1813, 1813, 1813, 2367, 2367, 2367, 3437, 3437, 3437, 3437, 3437, 3437), MM_by = c("A", "A", "A", "A", "B", "B", "B", "B", "B", "C", "A", "A", "B", "C", "A", "B", "C", "A", "A", "B", "B", "C", "C"), MM = c("aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi"), MM_annotation = c("*", "B", "*", "C", "A", "*", "C", "*", "A", "A", "C", "*", "A", "A", "*", "A", "A", "*", "C", "A", "*", "A", "*"), dur = c(400L, 467L, 66L, 887L, 693L, 247L, 473L, 147L, 260L, 1820L, 353L, 207L, 567L, 567L, 1060L, 1060L, 1060L, 1000L, 1620L, 306L, 2314L, 2300L, 320L), end = c(400, 867, 933, 1820, 693, 940, 1413, 1560, 1820, 1820, 2166, 2373, 2380, 2380, 3427, 3427, 3427, 4437, 6057, 3743, 6057, 5737, 6057), start = c(0, 400, 867, 933, 0, 693, 940, 1413, 1560, 0, 1813, 2166, 1813, 1813, 2367, 2367, 2367, 3437, 4437, 3437, 3743, 3437, 5737)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -23L))
解决方案
方法1:添加竖线分隔线段
提取每个线段的起止节点,用geom_vline绘制细竖线作为分隔,能清晰区分相邻线段:
library(dplyr) # 提取每个分组内的分割点(排除首尾端点) split_points <- df1 %>% group_by(Utterance, MM_by) %>% summarise(x = unique(c(start, end)), .groups = "drop") %>% filter(x != min(x, na.rm = TRUE) & x != max(x, na.rm = TRUE)) # 修改绘图代码,加入竖线分隔 ggplot(data = df1, aes(x = start, xend = end, y = MM_by, yend = MM_by, color = MM_annotation)) + geom_segment(size = 4) + # 添加黑色细竖线作为分隔 geom_vline(data = split_points, aes(xintercept = x), color = "black", linewidth = 0.5) + scale_y_discrete(name = NULL, limits = rev) + facet_wrap(~ Utterance, scales = "free_x", ncol = 1) + scale_colour_manual(values = c("*" = "white", "A" = "yellow", "B" = "lawngreen", "C" = "cyan"), name = "Gaze to")
方法2:添加矩形背景区分线段
给每个线段添加浅色矩形背景,通过色块边界自然区分相邻线段:
# 生成矩形背景数据,扩展y轴范围避免遮挡线段 rect_data <- df1 %>% mutate(y_min = as.numeric(factor(MM_by)) - 0.4, y_max = as.numeric(factor(MM_by)) + 0.4) ggplot(data = df1, aes(x = start, xend = end, y = MM_by, yend = MM_by, color = MM_annotation)) + # 先绘制浅色矩形背景 geom_rect(data = rect_data, aes(xmin = start, xmax = end, ymin = y_min, ymax = y_max), fill = "gray90", color = NA, inherit.aes = FALSE) + geom_segment(size = 4) + scale_y_discrete(name = NULL, limits = rev) + facet_wrap(~ Utterance, scales = "free_x", ncol = 1) + scale_colour_manual(values = c("*" = "white", "A" = "yellow", "B" = "lawngreen", "C" = "cyan"), name = "Gaze to")
方法3:调整线段间隙
给每个线段的起止点微调,让相邻线段间出现微小空白间隙,无需额外元素即可区分:
ggplot(data = df1 %>% mutate(start = start + 5, end = end - 5), aes(x = start, xend = end, y = MM_by, yend = MM_by, color = MM_annotation)) + geom_segment(size = 4) + scale_y_discrete(name = NULL, limits = rev) + facet_wrap(~ Utterance, scales = "free_x", ncol = 1) + scale_colour_manual(values = c("*" = "white", "A" = "yellow", "B" = "lawngreen", "C" = "cyan"), name = "Gaze to")
内容的提问来源于stack exchange,提问作者Chris Ruehlemann
相关产品推荐
相关产品推荐

