【问题标题】:Floating bar chart with dates as the plotted values in r浮动条形图,日期为 r 中的绘制值
【发布时间】:2015-12-16 05:28:18
【问题描述】:

我想绘制特定对象处于“活动”状态的日期范围,如下所示:

这个例子取自Wikipedia。这是数据:

df1 <- data.frame(
  name = c("Eazy-E", "DJ Yella", "Dr. Dre",
    "Ice Cube", "Arabian Prince", "MC Ren"),
  from = as.Date(c("01/01/1986", "01/01/1986", "01/01/1986",
    "01/01/1986", "01/01/1986","02/01/1988"), "%m/%d/%Y"),
  to = as.Date(c("08/01/1991", "08/01/1991", "07/01/1991",
    "12/01/1989", "07/01/1988", "08/01/1991"),"%m/%d/%Y"))

df1
            name       from         to
1         Eazy-E 1986-01-01 1991-08-01
2       DJ Yella 1986-01-01 1991-08-01
3        Dr. Dre 1986-01-01 1991-07-01
4       Ice Cube 1986-01-01 1989-12-01
5 Arabian Prince 1986-01-01 1988-07-01
6         MC Ren 1988-02-01 1991-08-01

我不知道该怎么做:

  1. 绘制日期值
  2. 制作浮动条形图

感谢您的任何意见。

【问题讨论】:

    标签: r date plot bar-chart


    【解决方案1】:

    它本身似乎不是条形图,更像是线条或矩形的集合。因此,这可以通过lines()rect() 甚至polygon() 来解决。我将展示第一个,希望你能明白要点。

    您的数据:

    dat <- structure(list(name = c("Eazy-E", "DJ Yella", "Dr. Dre", "Ice Cube", "Arabian Prince", "MC Ren"),
                          from = c("1986-01-01", "1986-01-01", "1986-01-01", "1986-01-01", "1986-01-01", "1988-02-01"),
                          to = c("1991-08-01", "1991-08-01", "1991-07-01", "1989-12-01", "1988-07-01", "1991-08-01")),
                     .Names = c("name", "from", "to"), row.names = c(NA, -6L), class = "data.frame")
    dat$from <- as.POSIXct(dat$from)
    dat$to <- as.POSIXct(dat$to)
    dat
    ##             name       from         to
    ## 1         Eazy-E 1986-01-01 1991-08-01
    ## 2       DJ Yella 1986-01-01 1991-08-01
    ## 3        Dr. Dre 1986-01-01 1991-07-01
    ## 4       Ice Cube 1986-01-01 1989-12-01
    ## 5 Arabian Prince 1986-01-01 1988-07-01
    ## 6         MC Ren 1988-02-01 1991-08-01
    

    一个解决方案:

    par(mar=c(2,8,0,0) + 0.1)
    plot(0, type='n', xlim=range(c(dat$from, dat$to)), ylim=c(1, nrow(dat)),
         main='', xlab='', ylab='', xaxt='n', yaxt='n')
    years <- seq.POSIXt(min(dat$from), max(dat$to), by='1 year')
    abline(v=years, lty=3, col='gray')
    axis(1, at=years, labels=format(years, '%Y'))
    axis(2, at=1:nrow(dat), labels=rev(dat$name), las=2)
    lines(x=as.POSIXct(c(apply(dat[,c('from','to')], 1, c, NA))),
          y=rep(nrow(dat):1, each=3),
          lwd=5)
    

    增加lwd 以获得更粗的线条。如果您想对其进行更多控制,请考虑以同样的方式使用rect

    【讨论】:

    • segments 可能比lines 更方便:segments(dat$from, rep(nrow(dat):1, 2), df$to, lwd=5, lend=1) (使用lend=1 使线的末端更接近,更好地指示它们的末端)。我想您可能会发现 seq(min(dat$from), max(dat$to), 'year') 可以与原始的 Date 对象一起正常工作 - 我认为不需要强制转换为 POSIX
    • 我同意(并且重写将使用segments),但此讨论伴随着“您可以使用linesrectpolygonsegments 或... ”。我希望 OP 了解如何解决基本问题,也许首先不是将其视为条形图,而是更多地视为条形图/线条图。很有趣,我知道,但这是视角。
    • 是的,我的 cmets 更多地是作为 OP 的提示。我并不是说您的帖子没有用 - 将其与折线图(带有粗线)相关联是明智的,并导致 y 轴坐标系通常比使用 @987654342 时更容易使用@.
    • 是的。其中一些答案真的可以持续页面,有多个食谱。和你一样,我认为展示一个并评论可能的替代方案是一种很好的帮助方式。谢谢!
    【解决方案2】:

    这是一种使用barchart 的方法。首先,绘制一个条形图,其中条形长度由结束日期给出,然后在此上面绘制一个白色条形图,条形长度由开始日期给出。使用axis.date 添加 x 轴标签。

    par(mar=c(5, 6, 2, 2))
    b <- barplot(as.numeric(df$to), horiz=TRUE, border='transparent', 
            xlim=range(c(df$from, df$to)), xaxt='n', yaxs='i',
            space=1)
    barplot(as.numeric(df$from), horiz=TRUE, space=1, add=TRUE, col='white', 
            border='transparent', xaxt='n', names.arg=df$name, las=1, 
            cex.names=0.8)
    axis(2, at=b[, 1], labels=FALSE, tick=FALSE)
    box(bty='l')
    axis.Date(1, pretty(df$from), cex.axis=0.8)
    

    【讨论】:

    • 很好地使用了axis.date,而不是我在回答中的笨拙方法。我没有考虑过双重绘制条形图,尽管它看起来更接近 OP 的引用图像。不错。
    猜你喜欢
    • 2016-10-30
    • 2021-05-07
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多