Visualizing with a Transition Plot - Super Useful!

Statistics
2017
Author

Cliff Weaver

Published

May 22, 2016

Transition plot

It’s closely related to the plotMat for plotting networks but aimed at less complex relations with only a one-way relation between two groups of states. Wait till you see this - it is something you can likely use all the time in your job!

Simulate some data

We start by creating some sample data:

library(kableExtra)

before <- sample(1:3, replace = TRUE, size = 500, prob = c(0.1, 0.4, 0.5))
after <- sample(1:3, replace = TRUE, size = 500, prob = c(0.3, 0.5, 0.2))
before <- factor(before, labels = c("None", "Moderate", "Major"))
after <- factor(after, labels = c("None", "Moderate", "Major"))
# Create the transition matrix
transition_matrix <- table(before, after)
# Create a table with the transitions
kbl(transition_matrix, caption = "Transitions") %>% 
  kable_styling(bootstrap_options = c("striped", "condensed", "responsive"), full_width = F, position = "center")
Transitions
None Moderate Major
None 9 31 8
Moderate 56 98 39
Major 83 122 54

Basic Example

This is simple to understand but understanding the flow can be challenging and time-consuming. Visualizing it using the transition plot gives a quick and more intuitive understanding:

library(Gmisc)
Loading required package: Rcpp
Loading required package: htmlTable
transitionPlot(transition_matrix)
The minimum width reached and the arrow at box no. '1' to no. '3' will not be shown. This is due to the fact that the lwd will generate a falsely strong arrow.
The minimum width reached and the arrow at box no. '1' to no. '1' will not be shown. This is due to the fact that the lwd will generate a falsely strong arrow.
The minimum width reached and the arrow at box no. '1' to no. '3' will not be shown. This is due to the fact that the lwd will generate a falsely strong arrow.
The minimum width reached and the arrow at box no. '1' to no. '1' will not be shown. This is due to the fact that the lwd will generate a falsely strong arrow.

Here you can see the thick lines representing the transition from that particular group into the next. So far I’ve used the graph for the same measure on left and right side but I guess your imagination sets the limit. It can just as well be two or more treatment arms with some discrete outcomes.

Basic Improvement - Arrows

Change the arrow type to my alternative arrow we get a nicer plot:

transitionPlot(transition_matrix, overlap_add_width = 1.3, type_of_arrow = "simple")

Basic Improvement - Arrows with Gradient

Added a white background to each arrow in order to visually separate the arrows (the overlay order can be customized with the overlap order parameter). To further enhance the transition add the option of a color gradient. To do this you need to specify arrow_type = 'gradient':

transitionPlot(transition_matrix, overlap_add_width = 1.3, type_of_arrow = "gradient")

Add Coloring

Additionally you can choose different colors for your boxes:

library(RColorBrewer)
transitionPlot(transition_matrix, txt_start_clr = "black", txt_end_clr = "black",
    fill_start_box = brewer.pal(n = 3, name = "Pastel1"), fill_end_box = brewer.pal(n = 6, name = "Pastel1")[4:6],
    overlap_add_width = 1.3, type_of_arrow = "gradient")

Add Proportions

Sometimes you might want to split the color of each box into two colors to illustrate a proportion. Note that the gradient color is a blend between the two proportions:

transitionPlot(transition_matrix, box_prop = cbind(c(0.3, 0.7, 0.5), c(0.5, 0.5, 0.4)),
    txt_start_clr = c("black", "white"), txt_end_clr = c("black", "white"),
    fill_start_box = brewer.pal(n = 3, name = "Paired")[1:2], fill_end_box = brewer.pal(n = 3, name = "Paired")[1:2],
    overlap_add_width = 1.3, type_of_arrow = "gradient")

Highlighting Arrows

Another interesting option may be to highlight a certain transition:

arr_clrs <- c(rep(grey(0.5), times = 3), c(grey(0.5), "black", grey(0.5)), rep(grey(0.5), times = 3))

transitionPlot(transition_matrix, arrow_clr = arr_clrs, overlap_order = c(1, 3, 2),
    box_prop = cbind(c(0.3, 0.7, 0.5), c(0.5, 0.5, 0.4)),
    txt_start_clr = c("black", "white"), txt_end_clr = c("black", "white"),
    fill_start_box = brewer.pal(n = 3, name = "Paired")[1:2], fill_end_box = brewer.pal(n = 3, name = "Paired")[1:2],
    overlap_add_width = 1.3, type_of_arrow = "gradient")

Summary

The function transitionPlot is included in the Gmisc package.

Another explanation and example can be found here: https://cran.r-project.org/web/packages/Gmisc/vignettes/transitionPlot.html