Pretty Timelines in R

A library for creating time based charts, like Gantt or timelines. Possible outputs include 'ggplot2' diagrams, 'plotly.js' graphs, 'Highcharts.js' widgets and data.frames. Results can be used in the 'RStudio' viewer pane, in 'RMarkdown' documents or in Shiny apps. In the interactive outputs created by vistime() and hc_vistime(), you can interact with the plot using mouse hover or zoom.

Donate CRAN dev Downloads Build Status codecov

vistime - Pretty Timeline Creation

Create interactive timelines or Gantt charts that are usable in the 'RStudio' viewer pane, in 'R Markdown' documents and in 'Shiny' apps. Hover the mouse pointer over a point or task to show details or drag a rectangle to zoom in. Timelines and their components can afterwards be manipulated using 'plotly_build()', which transforms the plot into a mutable list.

If you find vistime useful, please consider supporting its development:

Feedback welcome: [email protected]

  1. Installation
  2. Usage
  3. Arguments
  4. Value
  5. Examples
  6. Exporting
  7. Usage in Shiny apps
  8. Customization

1. Installation

To install the package from CRAN (v0.8.0):

if(!require("devtools")) install.packages("devtools")

2. Usage and standard arguments

vistime(data, start = "start", end = "end", groups = "group", events = "event", colors = "color", 
              fontcolors = "fontcolor", tooltips = "tooltip", linewidth = NULL, 
              title = NULL, show_labels = TRUE, background_lines = 11)

3. Arguments

parameter optional? data type explanation
data mandatory data.frame data.frame that contains the data to be visualised
start optional character the column name in data that contains start dates. Default: start
end optional character the column name in data that contains end dates. Default: end
groups optional character the column name in data to be used for grouping. Default: group
events optional character the column name in data that contains event names. Default: event
colors optional character the column name in data that contains colors for events. Default: color, if not present, colors are chosen via RColorBrewer.
fontcolors optional character the column name in data that contains the font color for event labels. Default: fontcolor, if not present, color will be black.
tooltips optional character the column name in data that contains the mouseover tooltips for the events. Default: tooltip, if not present, then tooltips are build from event name and date. Basic HTML is allowed.
linewidth optional numeric override the calculated linewidth for events. Default: heuristic value.
title optional character the title to be shown on top of the timeline. Default: empty.
show_labels optional logical choose whether or not event labels shall be visible. Default: TRUE.
background_lines optional integer the number of vertical lines to draw in the background to demonstrate structure. Default: 10.

4. Value

vistime returns an object of class plotly and htmlwidget.

5. Examples

Ex. 1: Presidents

pres <- data.frame(Position = rep(c("President", "Vice"), each = 3),
                   Name = c("Washington", rep(c("Adams", "Jefferson"), 2), "Burr"),
                   start = c("1789-03-29", "1797-02-03", "1801-02-03"),
                   end = c("1797-02-03", "1801-02-03", "1809-02-03"),
                   color = c('#cbb69d', '#603913', '#c69c6e'),
                   fontcolor = c("black", "white", "black"))
vistime(pres, events="Position", groups="Name", title="Presidents of the USA")

Ex. 2: Project Planning

data <- read.csv(text="event,group,start,end,color
                       Phase 1,Project,2016-12-22,2016-12-23,#c8e6c9
                       Phase 2,Project,2016-12-23,2016-12-29,#a5d6a7
                       Phase 3,Project,2016-12-29,2017-01-06,#fb8c00
                       Phase 4,Project,2017-01-06,2017-02-02,#DD4B39
                       Room 334,Team 1,2016-12-22,2016-12-28,#DEEBF7
                       Room 335,Team 1,2016-12-28,2017-01-05,#C6DBEF
                       Room 335,Team 1,2017-01-05,2017-01-23,#9ECAE1
                       Group 1,Team 2,2016-12-22,2016-12-28,#E5F5E0
                       Group 2,Team 2,2016-12-28,2017-01-23,#C7E9C0
                       1-217.0,category 2,2016-12-27,2016-12-27,#90caf9
                       3-200,category 1,2016-12-25,2016-12-25,#1565c0
                       3-330,category 1,2016-12-25,2016-12-25,#1565c0
                       3-223,category 1,2016-12-28,2016-12-28,#1565c0
                       3-225,category 1,2016-12-28,2016-12-28,#1565c0
                       3-226,category 1,2016-12-28,2016-12-28,#1565c0
                       3-226,category 1,2017-01-19,2017-01-19,#1565c0
                       3-330,category 1,2017-01-19,2017-01-19,#1565c0
                       4-399.7,moon rising,2017-01-13,2017-01-13,#f44336
                       8-831.0,sundowner drink,2017-01-17,2017-01-17,#8d6e63
                       9-984.1,birthday party,2016-12-22,2016-12-22,#90a4ae

6. Export of vistime as PDF or PNG

Once created, you can use plotly::export() for saving your vistime chart as PDF, PNG or JPEG:

chart <- vistime(pres, events="Position")
export(chart, file = "presidents.pdf")

Note that export requires the webshot package and additional arguments like width or height can be used (?webshot for the details).

7. Usage in Shiny apps

Since the result of any call to vistime(...) is a Plotly object, you can use plotlyOutput in the UI and renderPlotly in the server of your Shiny app to display your chart:

pres <- data.frame(Position = rep(c("President", "Vice"), each = 3),
                   Name = c("Washington", rep(c("Adams", "Jefferson"), 2), "Burr"),
                   start = c("1789-03-29", "1797-02-03", "1801-02-03"),
                   end = c("1797-02-03", "1801-02-03", "1809-02-03"),
                   color = c('#cbb69d', '#603913', '#c69c6e'),
                   fontcolor = c("black", "white", "black"))
  ui = plotlyOutput("myVistime"),
  server = function(input, output) {
    output$myVistime <- renderPlotly({
      vistime(pres, events="Position", groups="Name")

8. Customization

The function plotly_build turns your plot into a list. You can then use the function str to explore the structure of your plot. You can even manipulate all the elements there.

The key is to first create a simple Plotly example yourself, turning it into a list (using plotly_build) and exploring the resulting list regarding the naming of the relevant attributes. Then manipulate or create them in your vistime example accordingly. Below are some examples of common solutions.

Changing x-axis tick font size

The following example creates the presidents example and manipulates the font size of the x axis ticks:

pres <- data.frame(Position = rep(c("President", "Vice"), each = 3),
                   Name = c("Washington", rep(c("Adams", "Jefferson"), 2), "Burr"),
                   start = c("1789-03-29", "1797-02-03", "1801-02-03"),
                   end = c("1797-02-03", "1801-02-03", "1809-02-03"),
                   color = c('#cbb69d', '#603913', '#c69c6e'),
                   fontcolor = c("black", "white", "black"))
p <- vistime(pres, events="Position", groups="Name", title="Presidents of the USA")
# step 1: transform into a list
pp <- plotly_build(p)
# step 2: change the font size
pp$x$layout$xaxis$tickfont <- list(size = 28)

Changing y-axis tick font size

We have several y-axes, that's why we need to change the font size in all of them:

# loop through the yaxes and change the font size for each element:
for(i in grep("yaxis*", names(pp$x$layout))){
     pp$x$layout[[i]]$tickfont <- list(size = 28)

Changing events font size

The following example creates the presidents example and manipulates the font size of the events:

pres <- data.frame(Position = rep(c("President", "Vice"), each = 3),
                    Name = c("Washington", rep(c("Adams", "Jefferson"), 2), "Burr"),
                    start = c("1789-03-29", "1797-02-03", "1801-02-03"),
                    end = c("1797-02-03", "1801-02-03", "1809-02-03"),
                    color = c('#cbb69d', '#603913', '#c69c6e'),
                    fontcolor = c("black", "white", "black"))
p <- vistime(pres, events="Position", groups="Name", title="Presidents of the USA")
# step 1: transform into a list
pp <- plotly_build(p)
# step 2: loop over pp$x$data, and change the font size of all text elements to 28
for(i in 1:length(pp$x$data)){
    if(pp$x$data[[i]]$mode == "text") pp$x$data[[i]]$textfont$size <- 28
# or, using purrr:
# text_idx <- which(purrr::map_chr(pp$x$data, "mode") == "text")
# for(i in text_idx) pp$x$data[[i]]$textfont$size <- 28
# pp

Changing marker size

The following example a simple example using markers and manipulates the size of the markers:

dat <- data.frame(event = 1:4, start =  c("2019-01-01", "2019-01-10"))
p <- vistime(dat)
# step 1: transform into a list
pp <- plotly_build(p)
# step 2: loop over pp$x$data, and change the marker size of all text elements to 50px
for(i in 1:length(pp$x$data)){
    if(pp$x$data[[i]]$mode == "markers") pp$x$data[[i]]$marker$size <- 10
# or, using purrr:
# marker_idx <- which(purrr::map_chr(pp$x$data, "mode") == "markers")
# for(i in marker_idx) pp$x$data[[i]]$marker$size <- 10
# pp



  • hotfix: colors and fontcolors handling was broken.


  • internals (no exporting of helper functions, unit tests using testthat package, continuous integration using travis, test code coverage using covr)
  • activated Github Page:
  • argument showLabels has been renamed to show_labels for consistency. A warning message is shown.


  • we have a vignette now
  • events and ranges that are in the same group are now plotted directly below each other (in the past, all ranges were plotted first, followed by all events). Groups are sorted in order of first appearance but all items of one group are plotted together.
  • argument lineInterval is now deprecated. It was replaced by the new, more intuitive argument background_lines - the number of lines to draw in the background.
  • remove leading and trailing whitespaces of events and groups before drawing


  • Hotfix for broken y-axis labelling (introduced through new plotly package 4.8.0.)
  • events are now shown as circles (was: squares)
  • corrected font colors of Presidents example on help page


  • added a new argument showLabels to choose whether or not the event labels shall be drawn - improves layout of dense timelines
  • new argument lineInterval: the distance in seconds that vertical lines shall be drawn (to reduce plot size and increase performance). When omitted, a heuristic (as before) is used.
  • improved heuristic of vertical line drawing


  • line width calculation for ranges improved (thicker lines if less events happening simultaneously)
  • new parameter: linewidth to override the calculated line width for events
  • layout and labelling improvements
  • simplified examples
  • improved error checking


  • new parameters:
    • title (a title for the timeline)
    • tooltips (column name of data that contains individual tooltips)
    • fontcolors (column name of data that contains color of the event font)
  • ordering of groups in plot is now the same as the order of "groups" column in data
  • added more complex example and removed school data/example
  • changed colors argument default to "color" (i.e. if a column color is present in your data, it will be used for coloring the events)
  • bugfix if data contains only one event
  • bugfix where events where not correctly categorized into their respective groups
  • improved error checking
  • improved drawing of vertical lines for certain ranges
  • major improvement of intelligent levelling of ranges (" _-_¯-—")


  • improved error checking
  • various bugfixes


First public release on 29/01/2017

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.


1.2.1 by Sandro Raabe, 9 months ago

Report a bug at

Browse source code at

Authors: Sandro Raabe [aut, cre]

Documentation:   PDF Manual  

GPL-3 | file LICENSE license

Imports rlang, assertive.types, plotly, ggplot2, ggrepel, RColorBrewer

Suggests prettydoc, knitr, testthat, covr, highcharter

See at CRAN