4

Here is my reproducible example:

IND.factions <- rbind(c("Mughal Empire", "IND", "1526-1-1", "1857-1-1", "IND"),
                  c("Maratha Empire", "IND", "1674-1-1", "1818-1-1", "IND"),
                  c("Vijayanagara Empire", "IND", "1336-1-1", "1646-1-1", "IND"),
                  c("Deccan Sultanates", "IND", "1527-1-1", "1686-1-1", "IND"),
                  c("Bahmani Sultanate", "IND", "1347-1-1", "1527-1-1", "IND"),
                  c("EIC", "IND", "1612-1-1", "1757-1-1", "ENG"),
                  c("Company Rule", "IND", "1757-1-1", "1858-1-1", "ENG"),
                  c("Maratha Empire", "IND", "1858-1-1", "1947-1-1", "ENG")
                  )

IND.factions <- data.frame(IND.factions, stringsAsFactors = FALSE)
names(IND.factions) <- c("Person", "Country", "StartDate", "EndDate", "Origin")
IND.factions$StartDate <- as.Date(IND.factions$StartDate, "%Y-%m-%d")
IND.factions$EndDate <- as.Date(IND.factions$EndDate, "%Y-%m-%d")

What I want to visualise is something like a timeline:

library(ggplot2)
p <- ggplot(data = IND.factions, aes(y = Country)) + 
   geom_segment(aes(x = StartDate, xend = EndDate, yend = Country, color = Origin), size = 10, position = position_dodge(width = 10))
p

I couldn't find a solution for dodging the overlapping segments. Has anyone a workaround in mind? Of course I am aware that I could split it up into different factors, but that would be only my "worstcase" solution

Sandy Muspratt
  • 31,719
  • 12
  • 116
  • 122
  • I don't think dodging will help you. You could switch the x and y values and then use `coord_flip`, but that will only dodge the points that are identical and not the whole segments. I suspect you this requires some manual work. Why don't you use `Person` for the y values? – Roland Jul 02 '16 at 14:08
  • Are you going to have multiple values for `Country`? – Richard Telford Jul 02 '16 at 14:12
  • No, for this segment only one value for `Country`. The full plot would then contain several segments with other countries as well. – Fitzroy Hogsflesh Jul 02 '16 at 14:17
  • 1
    I think I asked a very similar question to this. This might be helpful: http://stackoverflow.com/questions/36227482/r-ggplot-dodging-geom-lines – Mike H. Jul 02 '16 at 14:21

1 Answers1

4

As far as I know, geom_segment does not allow dodging, but geom_linerange does.

library(ggplot2)

IND.factions <- rbind(c("Mughal Empire", "IND", "1526-1-1", "1857-1-1", "IND"),
                  c("Maratha Empire", "IND", "1674-1-1", "1818-1-1", "IND"),
                  c("Vijayanagara Empire", "IND", "1336-1-1", "1646-1-1", "IND"),
                  c("Deccan Sultanates", "IND", "1527-1-1", "1686-1-1", "IND"),
                  c("Bahmani Sultanate", "IND", "1347-1-1", "1527-1-1", "IND"),
                  c("EIC", "IND", "1612-1-1", "1757-1-1", "ENG"),
                  c("Company Rule", "IND", "1757-1-1", "1858-1-1", "ENG"),
                  c("Maratha Empire", "IND", "1858-1-1", "1947-1-1", "ENG")
                  )

IND.factions <- data.frame(IND.factions, stringsAsFactors = FALSE)
names(IND.factions) <- c("Person", "Country", "StartDate", "EndDate", "Origin")
IND.factions$StartDate <- as.Date(IND.factions$StartDate, "%Y-%m-%d")
IND.factions$EndDate <- as.Date(IND.factions$EndDate, "%Y-%m-%d")



ggplot(data = IND.factions, aes(x = Country, ymin = StartDate, ymax = EndDate, 
                                color = Origin, group = Person)) +
     geom_linerange(size = 10, position = position_dodge(.33)) +
     coord_flip()

enter image description here

Sandy Muspratt
  • 31,719
  • 12
  • 116
  • 122
  • 1
    thank you, that does it. Also already discussed here http://stackoverflow.com/questions/35322919/grouped-data-by-factor-with-geom-segment?lq=1 as I found out later – Fitzroy Hogsflesh Jul 03 '16 at 09:55
  • 1
    Generally speaking it seems that `geom_segment` is more ment to be fore arbitrary lines (e.g. between two dots on a scatterplot...) and `geom_linerange` was made for this kind of jobs. – Fitzroy Hogsflesh Jul 03 '16 at 09:56
  • And [here](http://stackoverflow.com/questions/21904364/how-to-jitter-dodge-geom-segments-so-they-remain-parallel/21922792#21922792) – Sandy Muspratt Jul 03 '16 at 10:22
  • 1
    `geom_segment` does seem to dodge, but only on `x` (or `y`) and not on `xend` (or `yend`). `geom_linerange` works great but has a problem. It doesn't allow arrows. I need arrows for my figure. I wonder if there is a way to get both arrows and dodging. – stacksia Apr 20 '21 at 01:59