Why plot a rectangle when only its height carries information? I would plot a line segment instead.
Following a great suggestion by @whuber, I've added transparent bars below the x-axis at 0 to highlight how projects overlap in time. And I removed the legend, opting instead to show the "name" of the project to the left of its segment.
Here is the R code; I use ggplot2.
library("lubridate")
library("tidyverse")
data <-
tribble(
~start_time, ~end_time, ~satisfaction, ~project,
"2022-01-01", "2022-01-31", 9, "A",
"2022-01-25", "2022-02-15", 8, "B",
"2022-03-10", "2022-04-08", 5, "C",
"2022-03-20", "2022-04-10", 6, "D"
) %>%
mutate(
across(ends_with("time"), as_date)
)
data %>%
ggplot() +
geom_segment(
aes(
x = start_time,
y = satisfaction,
xend = end_time,
yend = satisfaction,
color = project
),
size = 2
) +
geom_rect(
aes(
xmin = start_time,
ymin = 0,
xmax = end_time,
ymax = -1,
fill = project
),
alpha = 0.5
) +
geom_text(
aes(
x = start_time,
y = satisfaction,
label = project,
color = project
),
inherit.aes = FALSE,
nudge_x = -2,
fontface = "bold",
size = 5
) +
scale_x_date() +
scale_y_continuous(
breaks = c(0, 2, 4, 6, 8, 10),
limits = c(-1, 10),
expand = c(0, 0)
) +
# Draw bars in the margin as explained by @Axeman on StackOverflow:
# https://stackoverflow.com/a/73468680/9566484)
coord_cartesian(
ylim = c(0, 10),
clip = "off",
expand = FALSE
) +
theme_minimal() +
theme(
axis.title.x = element_blank(),
axis.ticks.x = element_line(),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_blank(),
legend.position = "none"
)
Created on 2022-08-24 with reprex v2.0.2