I have a series of lists describing duration (in days) of events, and I would like to plot this data as lines to compare the lists.
Below is some example data on what lunch options were served on which days at school. I have already parsed my data and this is the reduced form. Originally it was in the form of complex character strings.
soup = c(15:18)
grilledcheese = c(0:19)
pasta = c(3:13)
I want to create a graph similar to this one, with days on the x axis and soup
, grilled cheese
, and pasta
on the y axis:
I looked online and I'm not sure what kind of graph to use for this. Part of the difficulty is that the data does not start at 0 and the y axis should represent factors.
What I tried:
I tried plotting this in ggplot but it only takes data frames. I am wondering if there is a way to plot directly from lists. It seems like there should be a straightforward solution here that maybe I am missing.
I also tried this
plot(x = grilledcheese, y = rep(1, length(grilledcheese)))
which is closer to what I want, but I'm not sure how to plot multiple factors on the y axis.
First, let's get your data in a shape easier to handle with ggplot2:
library(tidyverse)
soup = c(15:18)
grilledcheese = c(0:19)
pasta = c(3:13)
df <- data.frame(soup_min = c(min(soup),max(soup)),
grilledcheese = c(min(grilledcheese),max(grilledcheese)),
pasta = c(min(pasta),max(pasta)))
df <- pivot_longer(df, cols = 1:3) %>%
group_by(name) %>%
mutate(minv = min(value),
maxv = max(value)) %>%
ungroup() %>%
select(-value) %>%
distinct()
# A tibble: 3 x 3
name minv maxv
<chr> <int> <int>
1 soup_min 15 18
2 grilledcheese 0 19
3 pasta 3 13
We can then plot the different elements you want: the starting and ending dots for each line, the lines themselves and the axis theme.
ggplot(df) +
geom_segment(aes(x = minv, xend = maxv, y = name, yend = name)) +
geom_point(aes(x = minv, y = name)) +
geom_point(aes(x = maxv, y = name)) +
scale_x_continuous(breaks = c(0:20),
labels = c(0:20),
limits = c(0,20),
expand = c(0,0)) +
theme(axis.ticks.x = element_line(size = 1),
axis.ticks.y = element_blank(),
axis.ticks.length =unit(.25, "cm"),
axis.line.x = element_line(size = 1),
panel.background = element_blank()) +
labs(x = "",
y = "")
We get this:
This should do the trick.
Now, if you want to have the ticks labels in-between the ticks, you might want to check here because you will have to reshape your data, and get the graph done once you have all the food types you want. Until, I just add spacing with-in the labels :
ggplot(df) +
geom_segment(aes(x = minv, xend = maxv, y = name, yend = name)) +
geom_point(aes(x = minv, y = name)) +
geom_point(aes(x = maxv, y = name)) +
scale_x_continuous(breaks = c(0:20),
labels = paste(" ",0:20),
limits = c(0,20),
expand = c(0,0)) +
theme(axis.ticks.x = element_line(size = 1),
axis.ticks.y = element_blank(),
axis.ticks.length =unit(.25, "cm"),
axis.line.x = element_line(size = 1),
panel.background = element_blank()) +
labs(x = "",
y = "")