Putting the cat in scatterplot

[This article was first published on Mango Solutions, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Clara Schartner, Data Scientist

It will come as no surprise that cats and ggplot are among our favourite things here at Mango, luckily there is an easy way to combine both.

Using the function annotation_custom in the popular ggplot2 package it is possible to display images on a plot i.e. points of a scatterplot. This way data can be displayed in a more fun, creative way.

In keeping with the cat theme I have chosen a data set about cats and a cat icon based on Mango the cat. The MASS package provides a data set called cats which contains the body weight, heart weight and sex of adult cats.

library(MASS)
data(cats)
head(cats)
set.seed(1234)
cats <- cats[sample(1:144, size = 40),]

First a normal scatterplot is defined on which the images will be plotted later:

library(ggplot2)
sCATter <-ggplot(data = cats, aes(x = Bwt, y = Hwt)) +
  geom_point(size = 0, aes(group = Sex, colour = Sex)) +
  theme_classic() +
  xlab("Body weight") +
  ylab("Heart weight") +
  ggtitle("sCATterplot") +
  theme(plot.title = element_text(hjust = 0.5)) +
  # create a legend
  scale_color_manual(
    values = c("#999999", "#b35900" ),
    name = "Cat",
    labels = c("Male cat", "Female cat")
  ) +
  guides(colour = guide_legend(override.aes = list(size = 10)))

Any png image can be used for the plot, however images with a transparent background are preferable.

library(png)
library(grid)
mCat <- readPNG("MaleCat.png")
feCat<- readPNG("FemaleCat.png")

In the last step the cats are iteratively plotted onto the plot using annotation_custom.

for (i in 1:nrow(cats)) {
  # distinguishing the sex of the cat
  if (cats$Sex[i] == "F") {
  image <- feCat
  } else{
  image <- mCat
  }
  sCATter = sCATter +
  annotation_custom(
    rasterGrob(image),
    xmin = cats$Bwt[i] - 0.6,
    xmax = cats$Bwt[i] + 0.6,
    ymin = cats$Hwt[i] - 0.6,
    ymax = cats$Hwt[i] + 0.6
  )
}

The cat´s paw trail is displaying a linear regression of heart on body weight. This can easily be added by computing a linear Regression, defining a grid to calculate the expected values and plotting cats on top of this data.

LmCat <- lm(Hwt~Bwt, data = cats)

steps <- 20
Reg <- data.frame(Bwt = 
                    seq(from = min(cats$Bwt), 
                            to = max(cats$Bwt), 
                            length.out = steps))
Reg$Hwt <- predict(LmCat, newdata = Reg)
sCATter <- sCATter + 
  geom_point(data = Reg, aes(Bwt, Hwt), size = 0)

paw <- readPNG("paw.png")
for (i in 1:nrow(Reg)) {
  sCATter = sCATter +
  annotation_custom(
    rasterGrob(paw),
    xmin = Reg$Bwt[i] - 0.6,
    xmax = Reg$Bwt[i] + 0.6,
    ymin = Reg$Hwt[i] - 0.6,
    ymax = Reg$Hwt[i] + 0.6
  )
}
sCATter

I hope you have as much fun as I did with this one!

To leave a comment for the author, please follow the link and comment on their blog: Mango Solutions.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)