Hands-on Exercise 9 Part I - Building Ternary Plot with R

Author

Alicia Loh

Published

June 10, 2024

Modified

June 11, 2024

Learning Objectives:

Getting Started

Ternary plots are a way of displaying the distribution and variability of three-part compositional data. (For example, the proportion of aged, economy active and young population or sand, silt, and clay in soil.) It’s display is a triangle with sides scaled from 0 to 1. Each side represents one of the three components. A point is plotted so that a line drawn perpendicular from the point to each leg of the triangle intersect at the component values of the point.

Installing and loading the required libraries

The following R packages will be used:

  • Tidyverse:

    • readr for importing delimited text file,

    • tidyr for tidying data,

    • dplyr for wrangling data and

  • ggtern, a ggplot extension specially designed to plot ternary diagrams. The package will be used to plot static ternary plots.

  • Plotly R, an R package for creating interactive web-based graphs via plotly’s JavaScript graphing library, plotly.js . The plotly R libary contains the ggplotly function, which will convert ggplot2 figures into a Plotly object.

Note: Version 3.2.1 of ggplot2 will be installed instead of the latest version of ggplot2. This is because the current version of ggtern package is not compatible to the latest version of ggplot2.

Code chunk below will be used to check if these packages have been installed and also will load them into the working R environment.

pacman::p_load(plotly, ggtern, tidyverse)

Importing Data into R

The Data

The Singapore Residents by Planning AreaSubzone, Age Group, Sex and Type of Dwelling, June 2000-2018 data will be used. The data set has been downloaded and included in the data sub-folder of the hands-on exercise folder. It is called respopagsex2000to2018_tidy.csv and is in csv file format.

Importing Data

The code chunk below uses the read_csv() function of readr package to import respopagsex2000to2018_tidy.csv into R

#Reading the data into R environment
pop_data <- read_csv("data/respopagsex2000to2018_tidy.csv") 

Preparing the Data

Use the mutate() function of dplyr package to derive three new measures, namely: young, active, and old.

#Deriving the young, economy active and old measures
agpop_mutated <- pop_data %>%
  mutate(`Year` = as.character(Year))%>%
  spread(AG, Population) %>%
  mutate(YOUNG = rowSums(.[4:8]))%>%
  mutate(ACTIVE = rowSums(.[9:16]))  %>%
  mutate(OLD = rowSums(.[17:21])) %>%
  mutate(TOTAL = rowSums(.[22:24])) %>%
  filter(Year == 2018)%>%
  filter(TOTAL > 0)

Plotting Ternary Diagram with R

Plotting a static ternary diagram

Use ggtern() function of ggtern package to create a simple ternary plot.

Active, Young, Old

#Building the static ternary plot
ggtern(data=agpop_mutated,aes(x=YOUNG,y=ACTIVE, z=OLD)) +
  geom_point()

Population Structure 2015

#Building the static ternary plot
ggtern(data=agpop_mutated, aes(x=YOUNG,y=ACTIVE, z=OLD)) +
  geom_point() +
  labs(title="Population structure, 2015") +
  theme_rgbw()

Plotting an interative ternary diagram

The code below create an interactive ternary plot using plot_ly() function of Plotly R.

0%20%40%60%80%100%100%80%60%40%20%0%100%80%60%40%20%0%
YoungActiveOldTernary MarkersTernary MarkersTernary Markers
# reusable function for creating annotation object
label <- function(txt) {
  list(
    text = txt, 
    x = 0.1, y = 1,
    ax = 0, ay = 0,
    xref = "paper", yref = "paper", 
    align = "center",
    font = list(family = "serif", size = 15, color = "white"),
    bgcolor = "#b3b3b3", bordercolor = "black", borderwidth = 2
  )
}

# reusable function for axis formatting
axis <- function(txt) {
  list(
    title = txt, tickformat = ".0%", tickfont = list(size = 10)
  )
}

ternaryAxes <- list(
  aaxis = axis("Young"), 
  baxis = axis("Active"), 
  caxis = axis("Old")
)

# Initiating a plotly visualization 
plot_ly(
  agpop_mutated, 
  a = ~YOUNG, 
  b = ~ACTIVE, 
  c = ~OLD, 
  color = I("black"), 
  type = "scatterternary"
) %>%
  layout(
    annotations = label("Ternary Markers"), 
    ternary = ternaryAxes
  )