I am currently working with ggplot2 to create a chart where I need to connect points by their ends, similar to the example image provided below:
To illustrate the issue, consider the following simple code:
library(tidyverse)
df <- data.frame(day=1:5, sales=c(10, 7, 5, 4, 3))
# Plotting
p1 <- df %>% ggplot(aes(day)) +
geom_line(aes(y = sales), linetype = 2, linewidth = 0.25) +
geom_point(aes(y = sales), size = 9, shape = 95) +
theme_minimal()
p1
The resulting plot is shown here:
As one can see, the line connects points by their center.
While using position = position_nudge
can "shift" the line with respect to the x-axis, for example, it does not achieve the desired outcome.
p2 <- df %>% ggplot(aes(day)) +
geom_line(aes(y = sales), linetype = 2, linewidth = 0.25, position = position_nudge(x = -0.155)) +
geom_point(aes(y = sales), size = 9, shape = 95) +
theme_minimal()
p2
Do you have any suggestions on how I can connect the points as shown in the example image? Any insights or alternative approaches would be greatly appreciated.
You could do it with geom_segment()
, but you have to define the start and end of each segment. The start could be the (day
, sales
) pair, but you'll need to subtract the relevant amount from day
to put it at the left edge of the point. You could then have the line run to lag(day)
and lag(sales)
, again, making sure that you add the appropriate amount to lag(day)
to put the segment at the right edge of the point. I used .125 and .075, respectively. It may take a bit of trial and error to figure out the exact right values.
library(tidyverse)
df <- data.frame(day=1:5, sales=c(10, 7, 5, 4, 3)) %>%
mutate(y_start = sales,
y_end = lag(sales),
x_start = day-.1,
x_end = lag(day) + .075)
df %>% ggplot() +
geom_point(aes(x=day, y = sales), size = 9, shape = 95) +
geom_segment(aes(x=x_start, y=y_start, xend=x_end, yend = y_end), linetype=2) +
theme_minimal()
Created on 2024-01-30 with reprex v2.0.2