Plotting historical periods in a timeline using R and vistime-package, BC not possible

271 Views Asked by At

for a research-project i want to plot a historical timeline with ruling-periods of ancient dynasties; seperated into male and female rulers.

I'm using R and the vistime-package (as suggested here). Generally it works, but the problem is that i can't figure out how to use dates BC; that means negative years.

A simple example of my code reads as follows:

# devtools::install_github("edgararuiz/gregorian")
# library(gregorian)
library(ggplot2)
library(vistime)

counter.chronology <- data.frame(
  namen = c("Ptolemaios V.","Ptolemaios VI.","Kleopatra I.","Kleopatra II.","Kleopatra III."),
  geschlecht = c("Männliche Regenten","Männliche Regenten","Weibliche Regentinnen","Weibliche Regentinnen","Weibliche Regentinnen"),
  antritt = as.Date(c("0197-01-01","0180-01-01","0194-01-01","0175-01-01","0141-01-01")),
  ende = as.Date(c("0180-01-01","0164-01-01","0176-01-01","0164-01-01","0130-01-01")),
  stringsAsFactors = FALSE
)

vistime(counter.chronology, col.event = "namen", col.group = "geschlecht", col.start = "antritt", col.end = "ende")

This works fine and produces a plot like this:

plot with wrong (positive) dates

But if i change the date-format to negative years -- for example "-0175-01-01" -- the plotting doesn't work out and i receive the error-message:

    Errore in charToDate(x) : 
    character string is not in a standard unambiguous format

I tried the gregorian-package and replaced as.Date with as_gregorian, but this seems imcompatible with vistime.

Does anyone know an easy solution for this problem? If negative dates are impossible, it would help to turn the plot around, in a way that it counts down an the x-axis from the highest to the lowest year.

A less important question, but also nice, if it's solved: It would be enough to use years as start and end dates. Months and days are unnecessary. But if i only enter, for example, "-0175 or the positive version "0175" the same error-message as above occurs. Therefore, i used 01-01 for month and day. It works anyway, because the timeline is not that detailed. To solve this would be nice, but it's not a must.

Thanks for all your replies and answers!

Best,

Flo

Edit after Allen response:

Another problem occured which you couldn't be aware of due to my short code-example. Sometimes there are overlapping ruling-periods. If i now enter another female reign which overlaps two of the other periods -- here, for example, "Arsinoe" -- , it looks awkward:

counter.chronology <- data.frame(
  namen = c("Ptolemaios V.", "Ptolemaios VI.",
            "Kleopatra I.","Arsinoe", "Kleopatra II.","Kleopatra III."),
  geschlecht = rep(c("Männliche Regenten", "Weibliche Regentinnen"), 
                   times = c(2, 4)),
  antritt = -c(197, 180, 194, 200, 175, 141),
  ende = -c(180, 164, 176, 150, 164, 130)
)

Overlapping periods

Is it possible to let ggplot place this overlapping bar automatically one stage above the others?

2

There are 2 best solutions below

0
On BEST ANSWER

Found another way usin the timevis package. Works well so far, also with overlapping periods:

library(timevis)

counter.chronology <- data.frame(
  content = c("Ptolemaios V.","Ptolemaios VI.","Kleopatra I.","Arsinoe","Kleopatra II.","Kleopatra III."),
  start = c("-000197-01-01","-000180-01-01","-000194-01-01","-000190-01-01","-000175-01-01","-000141-01-01"),
  end = c("-000180-01-01","-000164-01-01","-000160-01-01","-000145-01-01","-000164-01-01","-000130-01-01"),
  group = c(1,1,2,2,2,2),
  style = c("background-color: #f1d9a4; border-color: black;", 
            "background-color: #ceaf7a; border-color: black;",
            "background-color: #ca9865; border-color: black;")
)

timevis(
  counter.chronology, 
  groups = data.frame(
    id = 1:2, 
    content = c("Regenten", "Regentinnen"),
    width = 900
    )
)

Working solution

From a style-point i like the ggplot version better, but didn't found any solution for the problem with overlapping bars. Using gg_vistime would be my preferred solution -- since it combines the tools of vistime and ggplot. Unfortunately, like seen on the vistime-Github-page, there seems to be no practicable solution for using BC-dates, except for a complicated workaround: https://github.com/shosaco/vistime/issues/6

For now, I'm going with the timevis solution.

1
On

If you do this directly in ggplot, it is straightforward to simply use negative years as integer values on a continuous scale:

counter.chronology <- data.frame(
  namen = c("Ptolemaios V.", "Ptolemaios VI.",
            "Kleopatra I.", "Kleopatra II.","Kleopatra III."),
  geschlecht = rep(c("Männliche Regenten", "Weibliche Regentinnen"), 
                   times = c(2, 3)),
  antritt = -c(197, 180, 194, 175, 141),
  ende = -c(180, 164, 176, 164, 130)
)

library(geomtextpath)

ggplot(counter.chronology, aes(antritt, geschlecht)) +
  geom_textsegment(aes(xend = ende, yend = geschlecht, label = namen,
                       colour = namen), gap = FALSE,
                   linewidth = 30, textcolour = 'black') +
  scale_x_continuous(labels = abs) +
  scale_color_brewer(palette = 'Pastel1', guide = 'none') +
  theme_minimal(base_size = 16) 

enter image description here