Draw a chronological timeline with ggplot2

前端 未结 4 951
小蘑菇
小蘑菇 2020-12-07 23:23

I have data like

data = as.data.frame(  rbind(   c(\"1492\", \"Columbus sailed the ocean blue\"),
                                c(\"1976\", \"Americans lis         


        
相关标签:
4条回答
  • 2020-12-08 00:04

    This looks kind of OK... enter image description here

    dislocations <- c(-1,1,-.5)
    ggplot( data )
    + geom_text( aes(x = V1, y=dislocations, label = V2), position="jitter" )
    + geom_hline( yintercept=0, size=1, scale="date" )
    + geom_segment(  aes(x = V1, y=dislocations, xend=V1, yend=0, alpha=.7 ))
    

    but it still lacks a proper "time arrow", the background doesn't look right, and it labels values on the y axis.

    0 讨论(0)
  • 2020-12-08 00:08

    This seems like a better job for R's base graphics (really, this kind of thing probably better fits with a tool like Illustrator or something of that ilk).

    dat = as.data.frame(rbind(c("1492", "Columbus sailed the ocean blue"),
                           c("1976", "Americans listened to Styx"),
                           c("2008", "Financial meltdown")))
    dat$V1 <- as.Date(dat$V1,"%Y")
    dat$val <- c(-1,1,-0.5)
    
    plot(dat$V1,dislocations, type = "n",xaxt = "n",bty = "n", 
         xlab = "Time", ylab = "Dislocations")
    u <- par("usr")
    arrows(u[1], 0, u[2], 0, xpd = TRUE)
    points(dat$V1,dat$val,pch = 20)
    segments(dat$V1,c(0,0,0),dat$V1,dat$val)
    text(x=dat$V1,y=dat$val,labels=dat$V2,pos=c(4,2,2))
    

    produces something like this:

    enter image description here

    0 讨论(0)
  • 2020-12-08 00:11

    Sometimes the simplest graphics are the most difficult to create in ggplot2, but it is possible (and pretty).

    data =data.frame( V1=c(1492,1976,2008),V2=c("Columbus sailed the ocean blue","Americans listened to Styx","financial meltdown"),disloc=c(-1,1,-.5))
    dev.new()
    ggplot() +
        geom_segment(aes(x = V1,y = disloc,xend = V1),data=data,yend = 0) +
        geom_segment(aes(x = 900,y = 0,xend = 2050,yend = 0),data=data,arrow = arrow(length = unit(x = 0.2,units = 'cm'),type = 'closed')) +
        geom_text(aes(x = V1,y = disloc,label = V2),data=data,hjust = 1.0,vjust = 1.0,parse = FALSE) +
        geom_point(aes(x = V1,y = disloc),data=data) +
        scale_x_continuous(breaks = c(1492,1976,2008),labels = c("1492","1976","2008")) +
        theme_bw() +
        opts(axis.text.x = theme_text(size = 12.0,angle = 90.0),axis.text.y = theme_blank(),axis.ticks = theme_blank(),axis.title.x = theme_blank(),axis.title.y = theme_blank())
    

    enter image description here

    Note: this graphic was produced entirely in the ggplot2 Plot Builder in Deducer

    0 讨论(0)
  • 2020-12-08 00:13

    A little variation of the ggplot2 version above making use of geom_lollipop from ggalt and using cowplot for the nice background theme. Important to set the figure height as nice and small with a longer width (in my RMarkdown chunk I have fig.height = 3 and fig.width = 10)

    I've also used a (slightly adapted) function from this question which helps move the x-axis (the adapted function uses annotate rather than geom_hline. This allows me to add an arrow).

    Apologies, I have used my own data here for reasons of brevity. I need to get back to work!!

    library(ggplot2)
    library(dplyr)
    library(ggalt)
    library(cowplot)
    library(tibble)
    library(lubridate)
    
    #Create data to plot
    data <- tribble( ~start_date, ~event, ~displ,
                    ymd(20160201), "Initial meeting with Renfrewshire", 1,
                    ymd(20160430), "UBDC RAC submission", 0.7,
                    ymd(20160524), "College Ethics Approval", 0.5,
                    ymd(20160601), "UBDC RAC approval", -0.5,
                    ymd(20161101), "Agreeement in Principal", 0.3,
                    ymd(20170906), "DSA signed", 0.5,
                    ymd(20170921), "Data transferred", -0.5,
                    ymd(20180221), "Analysis complete", 0.5)
    
    
    #Function to shift x-axis to 0 adapted from link shown above
    
    shift_axis <- function(p, xmin, xmax, y=0){
          g <- ggplotGrob(p)
          dummy <- data.frame(y=y)
          ax <- g[["grobs"]][g$layout$name == "axis-b"][[1]]
          p + annotation_custom(grid::grobTree(ax, vp = grid::viewport(y=1, height=sum(ax$height))), 
                                ymax=y, ymin=y) +
            annotate("segment", y = 0, yend = 0, x = xmin, xend = xmax, 
                     arrow = arrow(length = unit(0.1, "inches"))) +
            theme(axis.text.x = element_blank(), 
                  axis.ticks.x=element_blank())
    
        }
    
    
    #Conditionally set whether text will be above or below the point
    vjust = ifelse(data$displ > 0, -1, 1.5)
    
    #plot
    p1 <- data %>% 
      ggplot(aes(start_date, displ)) +
      geom_lollipop(point.size = 1) +
      geom_text(aes(x = start_date, y = displ, label = event), data = data,
                hjust = 0, vjust = vjust, size = 2.5) +
      theme(axis.title = element_blank(),
            axis.text.y = element_blank(),
            axis.ticks.y = element_blank(),
            axis.line = element_blank(),
            axis.text.x = element_text(size = 8)) +
      expand_limits(x = c(ymd(20151201), ymd(20180501)), y = 1.2) +
      scale_x_date(breaks = scales::pretty_breaks(n = 9))
    
    #and run the function from above
    timeline <- shift_axis(p1, ymd(20151201), ymd(20180501))
    

    Produces....

    0 讨论(0)
提交回复
热议问题