R Codes

# Clear R Environment: 

rm(list = ls())

# ARDESTINE font used in this post can be download from https://fontzone.net/download/ar-destine
# Install and use external fonts in R: https://rpubs.com/chidungkt/392841
# Reference: https://twitter.com/hashtag/TidyTuesday?src=hashtag_click, 
#            https://github.com/MaiaPelletier/tidytuesday/blob/master/R/2020_Week29_Astronauts2.R


library(tidyverse)
library(ggtext)
library(extrafont)

# Get and pre-preocess the data: 

read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-07-14/astronauts.csv') -> astronauts 

astronauts %>%
  mutate(age_at_mission = year_of_mission - year_of_birth) -> astronauts

# Prepare text for annotation bubbles: 

texts <- tibble(
  age = c(77, 72, 15, 20),
  year = c(2010, 1985, 1968, 2005),
  text = c(
    "This is not a typo! Meet **John Herschel Glenn Jr.**, who travelled to space aged 77 in 1999. What a legend!",
    "1985 was the year that saw the **most astronauts in space**, with a total of 62 on 28 missions.",
    "The **two youngest astronauts** were Gherman Titov and Valentina Tereshkova, both aged 26. They each flew only one mission. It would be 1982 before the next female astronaut took to space.",
    "**Sergei Krikalev** went on his first of six missions aged 30. Only two astronauts have been on more missions: Franklin R. Chang-Diaz and Jerry L. Ross, who both started their careers in the 1980 NASA-9 selection."),
  vjust = rep(0.5, 4))

# Make draft plot: 

ggplot(astronauts) +
  geom_point(aes(y = year_of_mission, x = age_at_mission, colour = sex,
                 size = hours_mission, alpha = total_number_of_missions), show.legend = F) +
  scale_colour_manual(values = c(male = "#e1f7fa", female = "#ffa72b")) +
  labs(title = "
Ages through Time and Space
       ",
       subtitle = "  
**Astronauts have got older, missions have got longer, and starting younger is no guarantee  
of going more often.** 
  
Each dot is an astronaut on a mission. The larger the dot, the more hours the mission took,  
ranging from 0 to over 10,000 (14 months!). The more transparent the dot, the fewer times  
that astronaut went to space.  
The slope of age by year of mission is similar for <span style='color:#e1f7fa'>male</span> and <span style='color:#ffa72b'>female</span> astronauts, with a 20-year  
time lag.",
       x = "Age at start of mission",
       y = NULL,
       caption = "Data Source:  Mariya Stavnichuk and Tatsuya Corlett") +
  xlim(c(10, 85)) +
  geom_textbox(data = texts, aes(age, year, label = text, vjust = vjust),
               colour = "white", box.colour = "#1d1330", size = 3.8,
               fill = "#1d1330", family = "Corbel Light", maxwidth = unit(8, "lines"),
               hjust = 0.5, show.legend = F) +
  annotate("curve", x = 77, xend = 77, y = 2005, yend = 1999.5, curvature = 0, 
           size = 0.75, arrow = arrow(length = unit(2, "mm")), colour = "#938ca1") +
  annotate("curve", x = 65, xend = 60, y = 1985, yend = 1985, curvature = 0, 
           size = 0.75, arrow = arrow(length = unit(2, "mm")), colour = "#938ca1") +
  annotate("curve", x = 21, xend = 34, y = 1963, yend = 1981, curvature = 0.3, 
           size = 0.5, linetype = 2, arrow = arrow(length = unit(3, "mm")), colour = "#ffa72b") +
  annotate("curve", x = 21, xend = 26, y = 1970, yend = 1964, curvature = -0.4, 
           size = 0.75, arrow = arrow(length = unit(2, "mm")), colour = "#938ca1") +
  annotate("curve", x = 25, xend = 30, y = 2000, yend = 1990, curvature = -0.3, 
           size = 0.75, arrow = arrow(length = unit(2, "mm")), colour = "#938ca1") +
  theme_minimal() +  
  theme(plot.margin = unit(rep(1, 4), "cm")) + 
  theme(plot.background = element_rect(fill = "#1d1330", colour = NA),
        panel.grid = element_line(color = "#1d1330"),
        panel.background = element_rect(fill = "#1d1330", colour = NA),
        text = element_text(colour = "white", family = "Corbel Light"), 
        plot.title = element_text(hjust = 0, size = 24, family = "AR DESTINE"),
        axis.text = element_text(color = "white", size = 10),
        plot.subtitle = element_markdown(hjust = 0, size = 13, lineheight = 1),
        axis.title = element_text(color = "white", size = 10),
        axis.ticks = element_blank())
LS0tDQp0aXRsZTogJ0FnZXMgdGhyb3VnaCBUaW1lIGFuZCBTcGFjZScNCmF1dGhvcjogJ05ndXllbiBDaGkgRHVuZycNCnN1YnRpdGxlOiAiRGFpbHkgR3JhcGggU2VyaWVzIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgIyBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBoaWdobGlnaHQ6IHplbmJ1cm4NCiAgICAjIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdGhlbWU6ICJmbGF0bHkiDQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQotLS0NCg0KYGBge3Igc2V0dXAsaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIGNhY2hlID0gVFJVRSkNCg0KIyBodHRwczovL3N0ZWZhbnNhdmV2LmNvbS9ibG9nL2Nvc2luZS1zaW1pbGFyaXR5LWFsbC1wb3N0cy8NCiMgaHR0cHM6Ly9tYXNvbmdhbGxvLmdpdGh1Yi5pby9tYWNoaW5lL2xlYXJuaW5nLC9weXRob24vMjAxNi8wNy8yOS9jb3NpbmUtc2ltaWxhcml0eS5odG1sDQojIGh0dHBzOi8vdG93YXJkc2RhdGFzY2llbmNlLmNvbS93aGF0LWFyZS1wcm9kdWN0LXJlY29tbWVuZGF0aW9uLWVuZ2luZXMtYW5kLXRoZS12YXJpb3VzLXZlcnNpb25zLW9mLXRoZW0tOWRjYWI0ZWUyNmQ1DQojIGh0dHBzOi8vaGFja2Vybm9vbi5jb20vaW50cm9kdWN0aW9uLXRvLXJlY29tbWVuZGVyLXN5c3RlbS1wYXJ0LTEtY29sbGFib3JhdGl2ZS1maWx0ZXJpbmctc2luZ3VsYXItdmFsdWUtZGVjb21wb3NpdGlvbi00NGM5NjU5YzVlNzUNCg0KYGBgDQoNCg0KIVtdKEM6XFxVc2Vyc1xcQWRtaW5cXERvY3VtZW50c1xcYXVzMS5qcGcpDQoNCg0KIyBSIENvZGVzDQoNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQoNCg0KIyBDbGVhciBSIEVudmlyb25tZW50OiANCg0Kcm0obGlzdCA9IGxzKCkpDQoNCiMgQVJERVNUSU5FIGZvbnQgdXNlZCBpbiB0aGlzIHBvc3QgY2FuIGJlIGRvd25sb2FkIGZyb20gaHR0cHM6Ly9mb250em9uZS5uZXQvZG93bmxvYWQvYXItZGVzdGluZQ0KIyBJbnN0YWxsIGFuZCB1c2UgZXh0ZXJuYWwgZm9udHMgaW4gUjogaHR0cHM6Ly9ycHVicy5jb20vY2hpZHVuZ2t0LzM5Mjg0MQ0KIyBSZWZlcmVuY2U6IGh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9UaWR5VHVlc2RheT9zcmM9aGFzaHRhZ19jbGljaywgDQojICAgICAgICAgICAgaHR0cHM6Ly9naXRodWIuY29tL01haWFQZWxsZXRpZXIvdGlkeXR1ZXNkYXkvYmxvYi9tYXN0ZXIvUi8yMDIwX1dlZWsyOV9Bc3Ryb25hdXRzMi5SDQoNCg0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGdndGV4dCkNCmxpYnJhcnkoZXh0cmFmb250KQ0KDQojIEdldCBhbmQgcHJlLXByZW9jZXNzIHRoZSBkYXRhOiANCg0KcmVhZF9jc3YoJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9yZm9yZGF0YXNjaWVuY2UvdGlkeXR1ZXNkYXkvbWFzdGVyL2RhdGEvMjAyMC8yMDIwLTA3LTE0L2FzdHJvbmF1dHMuY3N2JykgLT4gYXN0cm9uYXV0cyANCg0KYXN0cm9uYXV0cyAlPiUNCiAgbXV0YXRlKGFnZV9hdF9taXNzaW9uID0geWVhcl9vZl9taXNzaW9uIC0geWVhcl9vZl9iaXJ0aCkgLT4gYXN0cm9uYXV0cw0KDQojIFByZXBhcmUgdGV4dCBmb3IgYW5ub3RhdGlvbiBidWJibGVzOiANCg0KdGV4dHMgPC0gdGliYmxlKA0KICBhZ2UgPSBjKDc3LCA3MiwgMTUsIDIwKSwNCiAgeWVhciA9IGMoMjAxMCwgMTk4NSwgMTk2OCwgMjAwNSksDQogIHRleHQgPSBjKA0KICAgICJUaGlzIGlzIG5vdCBhIHR5cG8hIE1lZXQgKipKb2huIEhlcnNjaGVsIEdsZW5uIEpyLioqLCB3aG8gdHJhdmVsbGVkIHRvIHNwYWNlIGFnZWQgNzcgaW4gMTk5OS4gV2hhdCBhIGxlZ2VuZCEiLA0KICAgICIxOTg1IHdhcyB0aGUgeWVhciB0aGF0IHNhdyB0aGUgKiptb3N0IGFzdHJvbmF1dHMgaW4gc3BhY2UqKiwgd2l0aCBhIHRvdGFsIG9mIDYyIG9uIDI4IG1pc3Npb25zLiIsDQogICAgIlRoZSAqKnR3byB5b3VuZ2VzdCBhc3Ryb25hdXRzKiogd2VyZSBHaGVybWFuIFRpdG92IGFuZCBWYWxlbnRpbmEgVGVyZXNoa292YSwgYm90aCBhZ2VkIDI2LiBUaGV5IGVhY2ggZmxldyBvbmx5IG9uZSBtaXNzaW9uLiBJdCB3b3VsZCBiZSAxOTgyIGJlZm9yZSB0aGUgbmV4dCBmZW1hbGUgYXN0cm9uYXV0IHRvb2sgdG8gc3BhY2UuIiwNCiAgICAiKipTZXJnZWkgS3Jpa2FsZXYqKiB3ZW50IG9uIGhpcyBmaXJzdCBvZiBzaXggbWlzc2lvbnMgYWdlZCAzMC4gT25seSB0d28gYXN0cm9uYXV0cyBoYXZlIGJlZW4gb24gbW9yZSBtaXNzaW9uczogRnJhbmtsaW4gUi4gQ2hhbmctRGlheiBhbmQgSmVycnkgTC4gUm9zcywgd2hvIGJvdGggc3RhcnRlZCB0aGVpciBjYXJlZXJzIGluIHRoZSAxOTgwIE5BU0EtOSBzZWxlY3Rpb24uIiksDQogIHZqdXN0ID0gcmVwKDAuNSwgNCkpDQoNCiMgTWFrZSBkcmFmdCBwbG90OiANCg0KZ2dwbG90KGFzdHJvbmF1dHMpICsNCiAgZ2VvbV9wb2ludChhZXMoeSA9IHllYXJfb2ZfbWlzc2lvbiwgeCA9IGFnZV9hdF9taXNzaW9uLCBjb2xvdXIgPSBzZXgsDQogICAgICAgICAgICAgICAgIHNpemUgPSBob3Vyc19taXNzaW9uLCBhbHBoYSA9IHRvdGFsX251bWJlcl9vZl9taXNzaW9ucyksIHNob3cubGVnZW5kID0gRikgKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMobWFsZSA9ICIjZTFmN2ZhIiwgZmVtYWxlID0gIiNmZmE3MmIiKSkgKw0KICBsYWJzKHRpdGxlID0gIg0KQWdlcyB0aHJvdWdoIFRpbWUgYW5kIFNwYWNlDQogICAgICAgIiwNCiAgICAgICBzdWJ0aXRsZSA9ICIgIA0KKipBc3Ryb25hdXRzIGhhdmUgZ290IG9sZGVyLCBtaXNzaW9ucyBoYXZlIGdvdCBsb25nZXIsIGFuZCBzdGFydGluZyB5b3VuZ2VyIGlzIG5vIGd1YXJhbnRlZSAgDQpvZiBnb2luZyBtb3JlIG9mdGVuLioqIA0KICANCkVhY2ggZG90IGlzIGFuIGFzdHJvbmF1dCBvbiBhIG1pc3Npb24uIFRoZSBsYXJnZXIgdGhlIGRvdCwgdGhlIG1vcmUgaG91cnMgdGhlIG1pc3Npb24gdG9vaywgIA0KcmFuZ2luZyBmcm9tIDAgdG8gb3ZlciAxMCwwMDAgKDE0IG1vbnRocyEpLiBUaGUgbW9yZSB0cmFuc3BhcmVudCB0aGUgZG90LCB0aGUgZmV3ZXIgdGltZXMgIA0KdGhhdCBhc3Ryb25hdXQgd2VudCB0byBzcGFjZS4gIA0KVGhlIHNsb3BlIG9mIGFnZSBieSB5ZWFyIG9mIG1pc3Npb24gaXMgc2ltaWxhciBmb3IgPHNwYW4gc3R5bGU9J2NvbG9yOiNlMWY3ZmEnPm1hbGU8L3NwYW4+IGFuZCA8c3BhbiBzdHlsZT0nY29sb3I6I2ZmYTcyYic+ZmVtYWxlPC9zcGFuPiBhc3Ryb25hdXRzLCB3aXRoIGEgMjAteWVhciAgDQp0aW1lIGxhZy4iLA0KICAgICAgIHggPSAiQWdlIGF0IHN0YXJ0IG9mIG1pc3Npb24iLA0KICAgICAgIHkgPSBOVUxMLA0KICAgICAgIGNhcHRpb24gPSAiRGF0YSBTb3VyY2U6ICBNYXJpeWEgU3Rhdm5pY2h1ayBhbmQgVGF0c3V5YSBDb3JsZXR0IikgKw0KICB4bGltKGMoMTAsIDg1KSkgKw0KICBnZW9tX3RleHRib3goZGF0YSA9IHRleHRzLCBhZXMoYWdlLCB5ZWFyLCBsYWJlbCA9IHRleHQsIHZqdXN0ID0gdmp1c3QpLA0KICAgICAgICAgICAgICAgY29sb3VyID0gIndoaXRlIiwgYm94LmNvbG91ciA9ICIjMWQxMzMwIiwgc2l6ZSA9IDMuOCwNCiAgICAgICAgICAgICAgIGZpbGwgPSAiIzFkMTMzMCIsIGZhbWlseSA9ICJDb3JiZWwgTGlnaHQiLCBtYXh3aWR0aCA9IHVuaXQoOCwgImxpbmVzIiksDQogICAgICAgICAgICAgICBoanVzdCA9IDAuNSwgc2hvdy5sZWdlbmQgPSBGKSArDQogIGFubm90YXRlKCJjdXJ2ZSIsIHggPSA3NywgeGVuZCA9IDc3LCB5ID0gMjAwNSwgeWVuZCA9IDE5OTkuNSwgY3VydmF0dXJlID0gMCwgDQogICAgICAgICAgIHNpemUgPSAwLjc1LCBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMiwgIm1tIikpLCBjb2xvdXIgPSAiIzkzOGNhMSIpICsNCiAgYW5ub3RhdGUoImN1cnZlIiwgeCA9IDY1LCB4ZW5kID0gNjAsIHkgPSAxOTg1LCB5ZW5kID0gMTk4NSwgY3VydmF0dXJlID0gMCwgDQogICAgICAgICAgIHNpemUgPSAwLjc1LCBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMiwgIm1tIikpLCBjb2xvdXIgPSAiIzkzOGNhMSIpICsNCiAgYW5ub3RhdGUoImN1cnZlIiwgeCA9IDIxLCB4ZW5kID0gMzQsIHkgPSAxOTYzLCB5ZW5kID0gMTk4MSwgY3VydmF0dXJlID0gMC4zLCANCiAgICAgICAgICAgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAyLCBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMywgIm1tIikpLCBjb2xvdXIgPSAiI2ZmYTcyYiIpICsNCiAgYW5ub3RhdGUoImN1cnZlIiwgeCA9IDIxLCB4ZW5kID0gMjYsIHkgPSAxOTcwLCB5ZW5kID0gMTk2NCwgY3VydmF0dXJlID0gLTAuNCwgDQogICAgICAgICAgIHNpemUgPSAwLjc1LCBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMiwgIm1tIikpLCBjb2xvdXIgPSAiIzkzOGNhMSIpICsNCiAgYW5ub3RhdGUoImN1cnZlIiwgeCA9IDI1LCB4ZW5kID0gMzAsIHkgPSAyMDAwLCB5ZW5kID0gMTk5MCwgY3VydmF0dXJlID0gLTAuMywgDQogICAgICAgICAgIHNpemUgPSAwLjc1LCBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMiwgIm1tIikpLCBjb2xvdXIgPSAiIzkzOGNhMSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsgIA0KICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQocmVwKDEsIDQpLCAiY20iKSkgKyANCiAgdGhlbWUocGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiIzFkMTMzMCIsIGNvbG91ciA9IE5BKSwNCiAgICAgICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfbGluZShjb2xvciA9ICIjMWQxMzMwIiksDQogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjMWQxMzMwIiwgY29sb3VyID0gTkEpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJ3aGl0ZSIsIGZhbWlseSA9ICJDb3JiZWwgTGlnaHQiKSwgDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLCBzaXplID0gMjQsIGZhbWlseSA9ICJBUiBERVNUSU5FIiksDQogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSAxMCksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X21hcmtkb3duKGhqdXN0ID0gMCwgc2l6ZSA9IDEzLCBsaW5laGVpZ2h0ID0gMSksDQogICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAid2hpdGUiLCBzaXplID0gMTApLA0KICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCg==