We will go through the Momocs package. This is one of my favorite R packages and I have used it extensively to analyze leaf shape when I was a PhD student at Davis. For example in Martinez et al., 2015. My collegue at the time, Dan Chitwood introduced me to the package where he used it to create some stunning work analyzing modulations in shape in Grape Leaves and violins!
The package has changed a bit since I last visited. It appears as though Vincent Bonhomme has really embraced Tidyverse and has updated the Momocs
package to reflect this. AND it appears that he is busily working on the Momocs 2.0 release (so stay tuned!).
library(Momocs)
library(tidyverse)
## Warning: package 'ggplot2' was built under R version 3.3.2
## Warning: package 'readr' was built under R version 3.3.2
## Warning: package 'dplyr' was built under R version 3.3.2
The Momocs package come with some great example datasets that we can use for examples, so we will just use these to make things easier.
A shape is described in euclidian space and the Shapes can be organized into a collection of coordinates.
a Coo object that carries:
A component named $coo
, a list of shapes (as matrix.ces); most of the time, a component named $fac, a data.frame to store covariates, either factors or numerics;possibly, other components of interest.
## Check out one of the data sets:
shapes
## Out (outlines)
## - 30 outlines, 836 +/- 255 coords (in $coo)
## - 0 classifiers (in $fac):
## # A tibble: 0 x 0
## - also: $ldk
str(shapes)
## coo : List of 30
## $ arrow : num [1:888, 1:2] 200 199 198 197 197 196 195 194 193 192 ...
## $ bone : num [1:810, 1:2] 200 199 198 197 196 195 194 193 192 191 ...
## $ buttefly: num [1:1077, 1:2] 200 200 200 199 199 199 198 198 197 197 ...
## $ cat : num [1:710, 1:2] 200 200 199 198 197 197 196 195 196 197 ...
## $ check : num [1:494, 1:2] 200 199 199 198 197 197 196 195 194 194 ...
## $ cross : num [1:806, 1:2] 200 200 199 198 198 197 197 196 195 195 ...
## $ dog : num [1:768, 1:2] 200 199 198 197 196 195 194 193 192 191 ...
## $ fish : num [1:943, 1:2] 200 199 198 197 196 195 194 193 192 191 ...
## $ hand : num [1:995, 1:2] 200 199 198 197 196 195 194 193 192 191 ...
## $ hands : num [1:1660, 1:2] 200 199 198 197 197 198 197 196 195 194 ...
## $ heart : num [1:554, 1:2] 200 199 198 197 197 198 199 198 198 197 ...
## $ info : num [1:514, 1:2] 200 199 198 197 196 195 194 193 192 191 ...
## $ lady : num [1:853, 1:2] 200 199 198 197 197 198 199 198 198 197 ...
## $ leaf : num [1:680, 1:2] 200 199 198 197 197 196 196 196 196 196 ...
## $ leaf2 : num [1:792, 1:2] 200 200 201 200 200 200 200 200 200 199 ...
## $ leaf3 : num [1:620, 1:2] 200 201 200 200 200 200 200 200 200 199 ...
## $ leaf4 : num [1:1300, 1:2] 200 199 198 198 197 196 195 194 193 194 ...
## $ moon : num [1:571, 1:2] 200 199 198 197 196 195 194 193 192 191 ...
## $ morph : num [1:719, 1:2] 200 199 198 197 197 198 197 196 195 194 ...
## $ parrot : num [1:534, 1:2] 200 199 198 197 196 196 195 194 193 193 ...
## $ penta : num [1:957, 1:2] 200 199 198 197 197 196 196 197 196 196 ...
## $ pigeon : num [1:1240, 1:2] 200 199 198 197 196 195 194 193 192 191 ...
## $ plane : num [1:853, 1:2] 200 199 198 197 197 198 197 196 195 194 ...
## $ puzzle : num [1:778, 1:2] 200 199 198 197 197 198 199 198 197 196 ...
## $ rabbit : num [1:662, 1:2] 200 199 198 197 196 195 194 193 192 191 ...
## $ sherrif : num [1:735, 1:2] 200 199 198 197 197 198 199 198 197 197 ...
## $ snail : num [1:930, 1:2] 200 199 198 197 196 195 194 193 192 191 ...
## $ star : num [1:1107, 1:2] 200 199 198 197 196 196 196 195 194 194 ...
## $ tetra : num [1:793, 1:2] 200 199 198 197 196 195 194 193 192 191 ...
## $ umbrella: num [1:724, 1:2] 200 200 199 199 198 197 197 196 195 194 ...
## fac : Classes 'tbl_df', 'tbl' and 'data.frame': 0 obs. of 0 variables
## ldk : list()
## Check out the coordinates of a single shape.
shapes[18] %>% head()
## [,1] [,2]
## [1,] 200 50
## [2,] 199 49
## [3,] 198 49
## [4,] 197 50
## [5,] 196 50
## [6,] 195 49
Since we are literally exploring shape, visualization of our data is extremely important. Momocs comes with a few different ways to visualize.
panel(shapes, names = TRUE) ## base R
cat <- shapes[4]
coo_plot(cat)
## #Rcatladies
coo_plot(cat, col="purple", main="Meow")
As discussed previously, a dataset (group of shapes) in Momocs is described as a Coo. Once you apply a method to that you get a Coe.
Coo + Morphometric method = Coe (x; y) coordinates + appropriate method = quantitative variables
Break for Discussion on S3 objects
** What is the difference between S3 and 4?** - S3 can only dispatch on it’s first argument, whereas S4 can dispatch on multiple arguments. If you want to be able to write methods for function foo that should do different things if given an object of class “bar” or given objects of class “bar” and “foobar”, or given objects of class “barfoo” and “foobar”, then S4 provides a far better way to handle such complexities. (ref)
More on S3: * Read Advanced R The S3 object system Chapter
So, let’s delve a bit more into our data.
class(shapes)
## [1] "Out" "Coo"
Does that make sense?
Another example of a more popular class - the tibble
class(iris)
## [1] "data.frame"
iris_tibble <- as_data_frame(iris)
## Tibbles have 3 classes
class(iris_tibble)
## [1] "tbl_df" "tbl" "data.frame"
Now back to Momocs….
## Let's check out the Cat Shape
cat <- shapes[4]
class(cat) # just a matrix
## [1] "matrix"
coo_plot(cat)
## Play with plot attributes
coo_plot(cat, col="pink", main="Meow")
## More attributes
?coo_plot
## Meeeeeow
coo_plot(coo_sample(cat, 125), points=TRUE, pch=20, main="125-pts Meow")
coo_plot(coo_sample(cat, 100), points=TRUE, pch=20, main="100-pts Meow")