【问题标题】:Using geom_segment to create a timeline visualization使用 geom_segment 创建时间线可视化
【发布时间】:2017-09-25 15:44:12
【问题描述】:

我正在尝试使用 ggplot 创建一个类似NYTimes 中生成的图表:

我想我已经接近了,但我不太确定如何分离出一些数据,以便获得正确的视图。我的数据是如下所示的政治职位持有人:

name,year_elected,year_left,years_in_office,type,party
Person 1,1969,1969,1,Candidate,Unknown
Person 2,1969,1971,2,Candidate,Unknown
Person 3,1969,1973,4,Candidate,Unknown
Person 4,1969,1973,4,Candidate,Unknown
Person 5,1971,1974,3,Candidate,Unknown
Person 1,1971,1976,5,Candidate,Unknown
Person 2,1971,1980,9,Candidate,Unknown
Person 6,1973,1978,5,Candidate,Unknown
Person 7,1973,1980,7,Candidate,Unknown
Person 8,1975,1980,5,Candidate,Unknown
Person 9,1977,1978,1,Candidate,Unknown

我已经使用下面的代码非常接近这个视图,但我认为我遇到的一个问题是不正确地绘制线段(例如,我似乎没有每个候选者都有一个片段),或者片段重叠/堆叠。我遇到的关键问题是我的公职人员名单大约有 60 人,但我的图表只画了大约 28 条线。

library(googlesheets)
library(tidyverse)

# I'm reading from a Google Spreadsheet
data <- gs_title("Council Members")
data_sj <- gs_read(ss = data, ws = "Sheet1")

ggplot(data, aes(year_elected, years_in_office)) +
  geom_segment(aes(x = year_elected, y = 0, 
                   xend = year_left, yend = years_in_office)) +
  theme_minimal()

上面的代码给了我:

提前感谢任何指点!

【问题讨论】:

  • 两种处理重叠的方法。 1) 使用实际的选举和离开日期,而不是分箱到整数年。 2)使用带有结束标记的半透明线来显示每个人。对于垂直部分,使用与 1) 相同的技术,这样当某人在同一年进出办公室时,他们仍然有两个不同的 x 值。
  • @JasonHeppler 你有确切的日期(不是四舍五入到年份)吗?
  • 感谢您的建议。不幸的是,我没有确切的日期,但我也担心即使我这样做了,问题也可能会持续存在,因为这些是市议会席位,并且有时会有一组成员同时被投票或投票。这可能会继续导致我看到的问题。
  • 我想我可以设置自己的“抖动”,并在重复年份之间添加一点日或月填充。我只是希望有一些方法可以解决这个问题,这并不意味着以奇怪的方式弄乱数据。

标签: r ggplot2


【解决方案1】:

如果你的数据框叫d,那么:

  • 将其转换为data.table
  • year_electer添加抖动
  • 将等效抖动添加到year_left
  • 添加组(例如)为您的样本着色

如果有很多点,使用ggrepel添加文本。

代码:

library(data.table)
library(ggplot2)
library(ggrepel)

d[, year_elected2 := jitter(year_elected)]
d[, year_left2 := year_left + year_elected2 - year_elected + 0.01]
d[, group := TRUE]
d[factor(years_in_office %/% 9) == 1, group := FALSE]

ggplot(d, aes(year_elected2, years_in_office)) +
    geom_segment(aes(x = year_elected2, xend = year_left2,
                     y = 0, yend = years_in_office, linetype = group),
                 alpha = 0.8, size = 1, color = "grey") +
    geom_point(aes(year_left2), color = "black", size = 3.3) +
    geom_point(aes(year_left2, color = group), size = 2.3) +
    geom_text_repel(aes(year_left2, label = name), ) +
    scale_colour_brewer(guide = FALSE, palette = "Dark2") +
    scale_linetype_manual(guide = FALSE, values = c(2, 1)) +
    labs(x = "Year elected",
         y = "Years on office") +
    theme_minimal(base_size = 10)

结果:

【讨论】:

  • 感谢您的建议!这似乎成功了。我稍微调整了一下,使用mutate而不是子集(但效果相同)使其对tidyverse更友好。
【解决方案2】:

为了记录并解决我对上述@PoGibas 答案的评论,这是我的tidyverse 版本:

data_transform <- data_sj %>% 
  mutate(year_elected_jitter = jitter(year_elected)) %>% 
  mutate(year_left_jitter = year_left + year_elected_jitter - year_elected + 0.01)

ggplot(data_transform, aes(year_elected, years_in_office, label = name)) +
  geom_segment(aes(x = year_elected_jitter, y = 0, xend = year_left_jitter, yend = years_in_office, color = gender), size = 0.3) +
  geom_text_repel(aes(year_left_jitter, label = name)) +
  theme_minimal()

【讨论】:

    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-19
    • 2015-03-30
    • 1970-01-01
    相关资源
    最近更新 更多