Ridgeline plot in R (Geology, Geochemistry, Petrology)

I am learning data visualization and statistics using R. 
Today I am learning Ridgeline plot/Joy plot. This plot shows the distribution of a numeric value for several groups. In geology, this would be very helpful to see the compositional distribution of samples (type of rocks, locality, mineral group etc.) 

Library 


library(ggplot2) 
library(tidyverse) 
library(ggridges) 
library(viridis) 
library(RColorBrewer) 


Load the test dataset (Iris data) 
data <- iris

view first six rows of iris dataset 
head(iris)

##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa

Visualization_1
ggplot(data, aes(x = Sepal.Length, y = Species)) +
  geom_density_ridges() + theme_ridges()




Visualization_2 
Adding color [scale_fill_viridis(name = "X", option = "A")]
Changing the "height" of the peak and including 0 [geom_density_ridges_gradient(scale = 3, rel_min_height = 0)]
p <- ggplot(data, aes(x = Sepal.Length, y = Species, fill = ..x..)) + 
  geom_density_ridges_gradient(scale = 3, rel_min_height = 0)
p <- p + scale_fill_viridis(name = "X", option = "A")
plot(p)



Visualization_3

Changing color [scale_fill_viridis(name = "Sepal.Length", option = "D")]

Changing the "height" of the peak and excluding 0 [geom_density_ridges_gradient(scale = 1, rel_min_height = 0)]
p <- ggplot(data, aes(x = Sepal.Length, y = Species, fill = ..y..)) + 
  geom_density_ridges_gradient(scale = 1, rel_min_height = 0.01)
p <- p + scale_fill_viridis(name = "Species", option = "D")
plot(p)



Visualization_4

p <- ggplot(data, aes(x = Sepal.Length, y = Species, fill = ..x..)) + 
  geom_density_ridges_gradient(scale = 1, rel_min_height = 0.01)
p <- p + scale_fill_distiller(name = "Sepal.Length", palette = "Spectral")
plot(p)



Visualization_5

p <- ggplot(data, aes(x = Sepal.Length, y = Species, fill = ..y..)) + 
  geom_density_ridges_gradient(scale = 1, rel_min_height = 0.01)
p <- p + scale_fill_distiller(name = "Species", palette = "RdYlBu")
plot(p)




Next, I use geological data. Dataset is mantle xenolith from PetDB.



Next, I use geological data. Dataset is mantle xenolith from PetDB (data-to-go).

This time, I used the 'data' sheet in excel. I named the file petdb_mantle_xenolith and saved as csv file.

Load the dataset

data <- read.csv("petdb_mantle_xenolith.csv")

Check the dataset

head(data)
##   SAMPLE_ID SAMPLE_NAME IGSN SAMPLE_TYPE LATITUDE LONGITUDE ELEVATION_MIN
## 1     11-01       11-01          Mineral  23.3994   58.1436            NA
## 2     11-10       11-10          Mineral  23.0494   58.6818            NA
## 3    11-33C      11-33C          Mineral  23.8822   56.6274            NA
## 4    13-113      13-113          Mineral  25.4489   56.1223            NA
## 5    13-121      13-121          Mineral  25.4489   56.0957            NA
## 6     13-33       13-33       Whole Rock  23.6489   56.9362            NA
##   ELEVATION_MAX TECTONIC_SETTING   ROCK.NAME           REFERENCE
## 1            NA        OPHIOLITE  LHERZOLITE PRIGENT, 2018[3698]
## 2            NA        OPHIOLITE  LHERZOLITE PRIGENT, 2018[3698]
## 3            NA        OPHIOLITE  LHERZOLITE PRIGENT, 2018[3698]
## 4            NA        OPHIOLITE  LHERZOLITE PRIGENT, 2018[3698]
## 5            NA        OPHIOLITE  LHERZOLITE PRIGENT, 2018[3698]
## 6            NA        OPHIOLITE HARZBURGITE PRIGENT, 2018[3698]
##            METHOD EXPEDITION.ID  SiO2 TiO2 Al2O3 Cr2O3 Fe2O3 Fe2O3T   FeO FeOT
## 1      EMP[82443]               47.91 0.38 10.61  0.64    NA     NA  3.20   NA
## 2 LA-ICPMS[82447]               56.81 0.04 49.72  0.69    NA     NA  3.17   NA
## 3      EMP[82445]               52.14 0.08 49.54 16.19    NA     NA 13.25   NA
## 4     CALC[82444]               54.31 0.07  5.19  0.61    NA     NA  6.56   NA
## 5 LA-ICPMS[82447]               39.93 0.03 50.18  0.31    NA     NA  1.93   NA
## 6     CALC[82438]                  NA   NA    NA    NA    NA     NA    NA   NA
##    NiO  MnO   MgO   CaO SrO Na2O  K2O P2O5 BaO   LOI H2O H2OM H2OP SO2 SO3 V2O3
## 1 0.07 0.05 19.43 12.72  NA 1.83 0.01   NA  NA    NA  NA   NA   NA  NA  NA 0.15
## 2 0.29 0.05 19.98 12.75  NA 1.08 0.01   NA  NA  6.43  NA   NA   NA  NA  NA 0.15
## 3 0.30 0.12 18.14 23.72  NA 0.17 0.01   NA  NA 13.95  NA   NA   NA  NA  NA 0.15
## 4 0.25 0.09 32.47  0.33  NA 0.06 0.02   NA  NA    NA  NA   NA   NA  NA  NA 0.09
## 5 0.40 0.06 17.22 23.86  NA 0.16 0.01   NA  NA  6.16  NA   NA   NA  NA  NA 0.13
## 6   NA   NA    NA    NA  NA   NA   NA   NA  NA    NA  NA   NA   NA  NA  NA   NA
##  .......


Using a ridge line plot, I try to see the relationship between lithology (rock type) and compositions. I use SiO2 as the x-axis.

p <- ggplot(data, aes(x = SiO2, y = ROCK.NAME, fill = ..y..)) + 
  geom_density_ridges_gradient(scale = 2, rel_min_height = 0.)
p <- p + scale_fill_distiller(palette = "RdYlBu")
plot(p)



Because low SiO2 contents are not realistic to peridotites (probably they are chromitites?), I screen the data. Here, I use the data which has SiO2 > 30 wt.%.


Data screening

data <- data %>% filter(SiO2 >= 30)


Reorder

I remove the legend and also rearranged the sample order (based on SiO2 contents). 

theme(legend.position = "none")


I order the ridgeline plotbased on its mean/median using forcats’ fct_reoder() 

function. y=fct_reorder(ROCK.NAME,SiO2)


p <- ggplot(data, aes(x = SiO2, y=fct_reorder(ROCK.NAME,SiO2), fill = ..y..)) + 
  geom_density_ridges_gradient(scale = 2, rel_min_height = 0.)
p <- p + scale_fill_distiller(palette = "RdYlBu")
p <- p + theme(legend.position = "none") #removing legend
plot(p)



Rename y-axis and change the theme

library(ggdark)
p <- ggplot(data, aes(x = SiO2, y=fct_reorder(ROCK.NAME,SiO2), fill = ..y..)) + 
  geom_density_ridges_gradient(scale = 2, rel_min_height = 0.)
p <- p + ylab("Lithology")
p <- p + scale_fill_distiller(palette = "RdYlBu")
p <- p + dark_theme_gray()
p <- p + theme(legend.position = "none") #removing legend
plot(p)




This ridgeline plot shows that metaperidotite resulted after deserpentinization has low SiO2 contents among ultramafic rocks. 

*Metaperidotite and eclogite are in mantle xenolith????


Keywords: geology in R, geochemistry in R, petrology in R, Ridgeline plot


References

https://r-graph-gallery.com/294-basic-ridgeline-plot.html

https://www.analyticsvidhya.com/blog/2021/06/ridgeline-plots-visualize-data-with-a-joy/

https://ggplot2.tidyverse.org/reference/scale_brewer.html