Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R base plotting, arrange multiple plots

Tags:

plot

r

I am working in RStudio and trying to make a 3x3 grid of the triangle plots built with the functions below. I’ve included a reproducible example, and the error I am running into is that the margins are too large to plot multiple plot, even though I am reducing the width and height. I’ve also tried saving these as png and loading them in to arrange with cowplot, but the figure is very blurry and I’m not sure how to adjust the text size or line thickness to make the figures more legible.

 #Data
iris$nrm.Sepal <- iris$Sepal.Width / iris$Sepal.Length
iris$nrm.Petal <- iris$Petal.Width / iris$Petal.Length
df_list <- split(iris, (iris$Species))

top.triangle <- function() {
  plot(my.y ~ my.x, data= my.data, axes=FALSE, ylab='', xlab="", 
       main='', xlim=c(0, 1), ylim=c(0, 1), xaxt="n", yaxt="n", asp=1)
  mtext("Here could be your title", 3, 5, font=2, cex=1.3, adj=.95)
  mtext("Position.2", 2, .75)
  mtext("Position.1", 3, 2)
  axis(side=2, las=1, pos=0)
  axis(side=3, las=1, pos=1)
  lines(0:1, 0:1)
}

bottom.triangle <- function() {
  points(my.x ~ my.y, data=my.data.2, xpd=TRUE)
  mtext("Position.2", 1, 1.5, at=mean(par()$usr[1:2]) + x.dist)
  mtext("Position.1", 4, 3, padj=par()$usr[1] + 10)
  x.at <- axisTicks(par()$usr[1:2], 0) + x.dist
  axis(side=1, las=1, pos=0, at=x.at, 
       labels=F, xpd=TRUE)
  mtext(seq(0, 1, .2), 1, 0, at=x.at)
  axis(4, las=1, pos=1 + x.dist)
  lines(0:1 + x.dist, 0:1, xpd=TRUE)
}

#loop for generating species specific plots
for(i in 1:(length(df_list))){
  current.strain <- as.character(df_list[[i]]$Species[1])

  #declare file for saving png
  # png(paste0("~.test.triangle_", current.strain, ".png"),  width=650, height=500)
  plot.new()
  my.data = iris
  my.x.top = (iris %>% filter(Species == current.strain) )$nrm.Petal  
  my.y.top = (iris %>% filter(Species == current.strain) )$nrm.Sepal
  my.x.bottom = (iris %>% filter(Species == current.strain) )$nrm.Petal 
  my.y.bottom = (iris %>% filter(Species == current.strain) )$nrm.Sepal 

  op <- par(mar=c(3, 2, 2, 2) + 0.1, oma=c(2, 0, 0, 2))
  top.triangle(my.y.top, my.x.top, my.data)

  bottom.triangle(my.y.bottom+x.dist, my.x.bottom, my.data)

  par(op)
  RP[[i]] <- recordPlot()
  dev.off()
}

#for margins too large error
graphics.off()
par("mar") 
par(mar=c(.1,.1,.1,.1))

#draw and arrange the plots
ggdraw() + 
  draw_plot(RP[[1]], x=0, y=0)

#Add remaining plots
#draw_plot(RP[[2]], x=.25, y=.25)
#draw_plot(RP[[3]], x=.25, y=.25)

enter image description here

(this is built off the answer I posted from this question, R base plot, combine mirrored right triangles )

like image 944
user1757654 Avatar asked Jun 01 '26 07:06

user1757654


1 Answers

To use plot solution at specified link, you need to adjust to the iris data including your calculated columns, nrm.Sepal and nrm.Petal inside both functions. Then, instead of split, consider by to pass subsets into both functions for plotting. However, the plot will only generate 1 X 3. It is unclear how 3 X 3 is generated. Your posted link above actually duplicates

Data

iris$nrm.Sepal <- iris$Sepal.Width / iris$Sepal.Length
iris$nrm.Petal <- iris$Petal.Width / iris$Petal.Length

Functions

top.triangle <- function(my.data) {

  plot(nrm.Sepal ~ nrm.Petal, data= my.data, axes=FALSE, ylab="", xlab="", 
       main='', xlim=c(0, 1), ylim=c(0, 1), xaxt="n", yaxt="n", asp=1)
  mtext(my.data$Species[[1]], 3, 5, font=2, cex=1.3, adj=.95)
  mtext("Position.2", 2, .75)
  mtext("Position.1", 3, 2)
  axis(side=2, las=1, pos=0)
  axis(side=3, las=1, pos=1)
  lines(0:1, 0:1)
}

bottom.triangle <- function(my.data) {
  x.dist <- .5
  my.data.2 <- transform(my.data, nrm.Sepal=nrm.Sepal + x.dist)

  points(nrm.Petal ~ nrm.Sepal, data=my.data.2, col="red", xpd=TRUE)
  mtext("Position.2", 1, 1.5, at=mean(par()$usr[1:2]) + x.dist)
  mtext("Position.1", 4, 3, padj=par()$usr[1] + 3)
  x.at <- axisTicks(par()$usr[1:2], 0) + x.dist
  axis(side=1, las=1, pos=0, at=x.at, 
       labels=FALSE, xpd=TRUE)
  mtext(seq(0, 1, 0.2), 1, 0, at=x.at, cex=0.7)
  axis(4, las=1, pos=1 + x.dist)
  lines(0:1 + x.dist, 0:1, xpd=TRUE)
}

Plot

par(mar=c(1, 4, 8, 6), oma=c(2, 0, 0, 2), mfrow=c(2,3))

by(iris, iris$Species, function(sub){
  top.triangle(sub)
  bottom.triangle(sub)
})

Plot Output

like image 72
Parfait Avatar answered Jun 03 '26 23:06

Parfait



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!