# A custom palette replacing ggplot2's default hues. Each colour approximates the
# real visible colour of that spectral class, so the legend runs blue (hot)
# through white and yellow to orange-red (cool), with teal marking white dwarfs.
star_cols <- c("O" = "#6D8DFF",
"B" = "#9BB0FF",
"A" = "#CAD7FF",
"F" = "#FFFFFF",
"G" = "#FFE87A",
"K" = "#FFB56B",
"M" = "#FF6B47",
"White dwarf" = "#4FD8C8")
# Astronomers plot temperature decreasing to the right AND on a log scale.
# transform_compose() chains the two transformations into one axis.
log_reversed <- transform_compose(transform_log10(), transform_reverse())
ggplot(hr, aes(x = temp, y = magnitude)) +
# Text annotations naming the three stellar populations the diagram reveals.
# These are placed before the points so labels sit underneath them.
annotate("text", x = 4300, y = -7.6, label = "Giants and supergiants",
color = "grey60", size = 3.4, fontface = "italic") +
annotate("text", x = 17000, y = 5.5, label = "Main sequence",
color = "grey60", size = 3.4, fontface = "italic", angle = -30) +
annotate("text", x = 13000, y = 12.6, label = "White dwarfs",
color = "grey60", size = 3.4, fontface = "italic") +
# Colour maps to spectral class, the third variable in the graph.
geom_point(aes(color = spectral), size = 3.4, alpha = 0.95) +
# Repelled labels for the recognisable stars only.
geom_text_repel(data = label_stars, aes(label = star),
color = "grey85", size = 3, seed = 7, box.padding = 0.6,
min.segment.length = 0, segment.color = "grey55") +
# Reversed log temperature axis with readable comma-formatted breaks.
scale_x_continuous(transform = log_reversed,
breaks = c(3000, 5000, 10000, 20000, 30000),
labels = label_comma()) +
# Reversed magnitude axis, because smaller magnitudes are brighter stars.
scale_y_reverse(breaks = seq(-10, 15, 5)) +
# Apply the custom colours and give the legend a meaningful title.
scale_color_manual(name = "Spectral Class", values = star_cols) +
labs(
title = "Hotter Stars Are Brighter, Except for the Ones That Break the Rule",
subtitle = "Temperature is reversed and logged and magnitude is reversed, following astronomical convention:\nhotter stars sit to the left, brighter stars sit higher",
x = "Surface Temperature (Kelvin, log scale)",
y = "Absolute Magnitude (smaller values are brighter)",
caption = "Source: stars dataset, dslabs R package (Rafael Irizarry)"
) +
# theme_minimal() replaces ggplot2's default grey theme, then a dark panel and
# light text are applied so the star colours read the way they would in a
# night sky rather than washing out against white.
theme_minimal(base_size = 12) +
theme(
plot.background = element_rect(fill = "#11141C", color = NA),
panel.background = element_rect(fill = "#11141C", color = NA),
panel.grid.major = element_line(color = "#2A2F3D", linewidth = 0.3),
panel.grid.minor = element_blank(),
text = element_text(color = "grey85"),
plot.title = element_text(color = "white", face = "bold", size = 14),
plot.subtitle = element_text(color = "grey70", size = 9.5),
plot.caption = element_text(color = "grey55", hjust = 0, size = 8),
axis.text = element_text(color = "grey75"),
legend.key = element_blank()
)