Reproducing a lollipop graph with ggplot2

75 views Asked by At

I want to create a lollipop graph something like given below: enter image description here

So for I got the following: enter image description here

using the following code

# Library
library(tidyverse)
 
# Create data
df1 <- 
  data.frame(
    x = c(2014, 2014, 2017, 2017, 2021, 2021)
  , y = c(1, -1, 1, -1, 1, -1)
  )


df1

# plot
ggplot(data = df1, aes(x = x, y = y)) +
  geom_segment(aes(x = x, xend = x, y = 0, yend = y)) +
  geom_segment(aes(x = 2014, xend = 2021, y = 0, yend = 0)) +
  geom_point(
      size   = 5
    , color  = "red"
    , fill   = alpha("orange", 0.3)
    , alpha  = 0.7
    , shape  = 21
    , stroke = 2
    ) +
  theme_void()
1

There are 1 answers

0
Peter On BEST ANSWER

Here's a possible approach which could be adapted to suit specific requirements...

You may need to adjust the parameters to suit your data and graphical device.

The balance of work done within the call to ggplot and the dataframe is fairly arbitrary; the setting of y and x coordinates for the various elements of the diagram could be set in the data frame.

library(ggplot2)
library(dplyr)
library(ggforce)
library(ggtext)

# Assumed data
df2 <- 
  data.frame(
    start = c(2014, 2017, 2018, 2021),
    qual = c("BSc", "MRes", "Phd", "DS" ),
    loc = paste("Uni", LETTERS[1:4])) |> 
  mutate(qual = factor(qual, levels = qual, ordered = TRUE),
         lab = paste0("**", qual, "**<br>", loc),
         dur = paste0(start, "\n-\n", lead(start)),
         dur = stringr::str_replace(dur, "NA", "now"))


ggplot(data = df2) +
  geom_segment(aes(x = -Inf, xend = Inf, y = 0, yend = 0)) +
  geom_segment(aes(x = qual, xend = qual, y = 0, yend = rep(c(0.75, -0.75), 2))) +
  geom_point(aes(x = qual, y = 0), size = 3)+
  geom_circle(aes(x0 = 1:4, y0 = rep(c(1, -1), 2), r = 0.35),
              fill = "aquamarine4",
              colour = NA)+
  geom_richtext(aes(x = qual, y = rep(c(-0.5, 0.5), 2), label = lab),
            size = 6,
            family = "serif",
            colour = "aquamarine4",
            label.colour = NA)+
  geom_text(aes(x = qual, y = rep(c(1, -1), 2), label = dur),
            colour = "white",
            size = 6,
            family = "serif") +
  ylim(-1.5, 1.5) +
  theme_void() +
  coord_fixed()

Created on 2023-06-24 with reprex v2.0.2