Search code examples
rplotmultiple-axes

How to plot multiple graphs (faceting) using twoord.plot () in R?


I have data that looks like this:

height <- c(1,2,3,4,2,4,6,8)
weight <- c(12,13,14,15,22,23,24,25)
person <- c("Jack","Jim","Jill","Tess","Jack","Jim","Jill","Tess")
set <- c(1,1,1,1,2,2,2,2)
dat <- data.frame(set,person,height,weight)

I'm trying to plot a graph with same x-axis(person), and 2 different y-axis (weight and height) using the twoord.plot function from the plotrix package. However, I do not know how to facet the plots like in ggplot2.

For example, if my plots could overlay in ggplot2, my code would look something like this:

ggplot(data = dat, aes(x = person, y = weight)) + 
  geom_point(color = "red") + facet_wrap(~set, scales="free") 
#And similarly have the height on the other axis.

Any idea on how to achieve this in twoord.plot()?


Solution

  • I find this plot really confusing, but this seems to be more or less what plotrix::twoord.plot does, so let me know if this is what you had in mind.

    In ggplot2, a second axis has to be based on a transformation of the first axis. So, we first transform the plotted height values to put them within the same range as the weight values (so they'll appear within the y-range of a graph based on weight). Then we do the inverse transformation to the scale of the second y-axis (so that the y-axis scale will correspond to the actual height values in the data).

    ggplot(dat, aes(person)) + 
      geom_point(aes(y=weight), colour="blue") + 
      geom_point(aes(y=height/mean(height/weight)), colour="red", shape=17) +
      scale_y_continuous(sec.axis=sec_axis(~ . * mean(dat$height/dat$weight), 
                                           breaks=seq(0,max(dat$height),1),
                                           name="height")) +
      theme_classic() +
      theme(axis.text.y.right=element_text(colour="red"),
            axis.text.y=element_text(colour="blue"),
            axis.title.y.right=element_text(colour="red"),
            axis.title.y=element_text(colour="blue"))
    

    enter image description here

    This seems more intuitive to me, especially if the measurements of each person are (implicitly) ordered in time:

    ggplot(dat, aes(weight, height, label=person, group=person)) +
      geom_line(colour="grey70") +
      geom_text()
    

    enter image description here