Hands-on Exercise 5.1

Author

Zachary Wong

Published

February 2, 2024

Modified

March 7, 2024

Creating Ternary Plot with R

Overview

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.

In this hands-on, you will learn how to build ternary plot programmatically using R for visualising and analysing population structure of Singapore.

The hands-on exercise consists of four steps:

  • Install and launch tidyverse and ggtern packages.

  • Derive three new measures using mutate() function of dplyr package.

  • Build a static ternary plot using ggtern() function of ggtern package.

  • Build an interactive ternary plot using plot-ly() function of Plotly R package.

Installing and Launching R Packages

For this exercise, two main R packages will be used in this hands-on exercise, they are:

  • 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.

We will also need to ensure that selected tidyverse family packages namely: readr, dplyr and tidyr are also installed and loaded.

In this exercise, 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.

The code chunks below will accomplish the task.

pacman::p_load('plotly', 'tidyverse')
Note

Due to some technical issue, ggtern is currently not available for downloading via cran. We need to download ggtern from the archive by using the code chunk below. The latest archive version is 3.4.1.

require(devtools)
install_version("ggtern", version = "3.4.1", repos = "http://cran.us.r-project.org")

Next, load ggtern package into R environment by using the code chunk below.

library(ggtern)

Preparing the Data

The Data

For the purpose of this hands-on exercise, the Singapore Residents by Planning AreaSubzone, Age Group, Sex and Type of Dwelling, June 2011-2020 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 respopagesexfa2011to2020 and is in csv file format.

Importing the Data

To import respopagsex2000to2018_tidy.csv into R, read_csv() function of readr package will be used.

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

Preparing the Data

#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 in R

Plotting a Static Ternary Diagram

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

#Building the static ternary plot
ggtern(data=agpop_mutated,aes(x=YOUNG,y=ACTIVE, z=OLD)) +
  geom_point()
#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 Interactive Ternary Diagram

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

# 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
  )