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.
CodePudding user response:
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()
Data
# A tibble: 3 x 3
name minv maxv
<chr> <int> <int>
1 soup_min 15 18
2 grilledcheese 0 19
3 pasta 3 13
Graph
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.
Extra custom
Now, if you want to have the ticks labels in-between the ticks, you might want to check
CodePudding user response:
You will first need to engineer your data into a data frame. You could do, e.g.
soup = c(15:18)
grilledcheese = c(0:19)
pasta = c(3:13)
## make dataframe
library(tidyverse)
my_x_axis <- as_tibble(seq(0,20))
names(my_x_axis) <- 'x'
my_x_axis %>% mutate(soup_y = 1*ifelse(as.numeric(x %in% soup) == 1, 1, NA)) %>%
mutate(grilledcheese_y = 2*ifelse(as.numeric(x %in% grilledcheese) == 1, 1, NA)) %>%
mutate(pasta_y = 3*ifelse(as.numeric(x %in% pasta) == 1, 1, NA)) -> data
Here, I use the knowledge that your x axis values are between 0 and 20. You could also do choose them by, e.g. by min(c(soup,grilledcheese,pasta))
and min(c(soup,grilledcheese,pasta))
or some other logic.