3
$\begingroup$

I'm trying to plot a collection of items where each item has an x-range, and a y-value. The below variation of a bar chart is what I had in mind, but I can't find a software tool that appears designed to plot it.

E.g., perhaps comparing the customer satisfaction for four construction projects that took place in a 10-week period. (Example edited for clarity)

The goal is to be able to visualize the heights of these different items, while also taking into account their possibly-overlapping ranges. A kind of combination of a timeline chart and a bar chart.

You could hack an area chart to mostly accomplish the design below, but is there a type of graph actually designed for this kind of data?

Ex: Bar Chart with overlapping x-ranges

$\endgroup$
2
  • $\begingroup$ Do the y-values represent total funding for each period or per-week funding? This bar chart might be appropriate in the latter case but is a gross visual exaggeration in the former. $\endgroup$
    – whuber
    Commented Aug 23, 2022 at 18:28
  • $\begingroup$ @whuber Ah, true - this was an example use-case, and I should've gone with something not directly-dependent on the duration of the event. Changed to 'customer satisfaction'. $\endgroup$ Commented Aug 23, 2022 at 19:07

2 Answers 2

5
$\begingroup$

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

$\endgroup$
3
  • 1
    $\begingroup$ +1. Because height is important, rather than distances between heights, I would (subtly) emphasize that by drawing the $y=0$ axis. This incidentally avoids having to specify coordinate limits, because ggplot will automatically expand them to include this line. Then, since you're putting pen to paper (as it were), why not color this axis according to the line segments hovering above it? That would make accurate assessment of the amount (=duration) of overlap easy. $\endgroup$
    – whuber
    Commented Aug 23, 2022 at 22:38
  • 2
    $\begingroup$ @whuber Thanks for the great suggestion to highlight time overlap on the x-axis. $\endgroup$
    – dipetkov
    Commented Aug 23, 2022 at 23:41
  • $\begingroup$ That is definitely a good point; the overlap is important, the height is important,though but the 'area' of each rectangle is basically meaningless. I love the joint lines+timeline, but I was hoping there was something simpler, or some more drastic frame-shift. I'll leave this open till tomorrow, just in case $\endgroup$ Commented Aug 24, 2022 at 17:42
1
$\begingroup$

A similar option for non-overlapping data ranges, especially where the bar area has meaning, could be a Marimekko/Mosaic plot.

Nivo Marimekko plot

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.