Assigning matrix name as plot title in R

Viewed 246

I'm producing a series of plots in R Studio with only the data source changing between them. Instead of manually editing the title of each, I'd like to automatically assign the plot title to be the name of the data source (a matrix). I'm struggling to conceptualize the logic flow here though. Overly simplified code example:

a<-matrix(1:10, ncol = 10,nrow=10)
b<-matrix(10:20,ncol=10,nrow=10)
plot(a) 
   mtext(side=3, "a") #I'm using mtext instead of main because the plotting function I use doesn't support 'main'
plot(b)
   mtext(side=3, "b")

So in this example, I'd want the main title of the first plot to be "a", and the second to be "b"; however, the way it's written now I need to manually adjust mtext(side=3,"X". I'd like to have the mtext statement read the matrix name and use that. I'll admit, this is a bit beyond my abilities. Any assistance is appreciate!

My actual code is not going to be reproducible due to a lack of source data, but as requested in comments, it follows:

source<-n20DO1 #source data used to generate comm
comm<-bn20DO1  #actual data being used, this is the one with the title

Low<-count(source$DObin==1)[2,2]
Low<-if(is.na(Low)) {Low <- 0} else {count(source$DObin==1)[2,2]}
Mod<-count(source$DObin==2)[2,2]
Mod<-if(is.na(Mod)) {Mod <- 0} else {count(source$DObin==2)[2,2]}
High<-count(source$DObin==3)[2,2]
High<-if(is.na(High)) {High <- 0} else {count(source$DObin==3)[2,2]}
LMH <- matrix(c(Low, Mod, High),ncol=1,byrow=TRUE)
colnames(LMH) <- c("Count")
rownames(LMH) <- c("Low","Mod", "High")
LMH <- as.table(LMH)
LMH

tries=20
NMDS20=metaMDS(comm, k=2,try=tries)
treat=c(rep("Low",Low),rep("Moderate",Mod),rep("High",High))
ordiplot(NMDS20,type="n",choices=c(1,2),xaxt="n",yaxt="n", 
         xlab="nmds1",ylab="nmds2")
colors=c(rep("black",Low),rep("yellow",Mod),rep("red",High))
for(i in unique(treat)) {
        ordihull(NMDS20$point[grep(i,treat),],draw="polygon",
                 groups=treat[treat==i],col=colors[grep(i,treat)],label=F) } 
orditorp(NMDS20,col=c(rep("black",Low),rep("yellow",Mod),rep("red",High)),
         air=0.01,cex=1.25,display="species")
mtext(side=3,"20 DO") #This is where I want the title adjusted
mtext(side=1,"Stress =" )
mtext(side=1,padj=1, round(NMDS20$stress, 4))
2 Answers

Here's a simple approach with writing a custom function using substitute:

my_mtext <- function(mat)mtext(side = 3, text = substitute(mat))
plot(a)
my_mtext(a)

enter image description here I'll admit that help(substitute) isn't the most helpful thing in the world:

Substitute returns the parse tree for the (unevaluated) expression expr

This means that substitute returns the unevaluated expression for mat rather than the matrix itself. Therefore you can use the symbol as text in your plot.

As a side note, the Details from help kind of are helpful:

The typical use of substitute is to create informative labels for data sets and plots.

Edit Now with your new code:

makePlot <- function(source, comm) {
Low<-count(source$DObin==1)[2,2]
Low<-if(is.na(Low)) {Low <- 0} else {count(source$DObin==1)[2,2]}
Mod<-count(source$DObin==2)[2,2]
Mod<-if(is.na(Mod)) {Mod <- 0} else {count(source$DObin==2)[2,2]}
High<-count(source$DObin==3)[2,2]
High<-if(is.na(High)) {High <- 0} else {count(source$DObin==3)[2,2]}
LMH <- matrix(c(Low, Mod, High),ncol=1,byrow=TRUE)
colnames(LMH) <- c("Count")
rownames(LMH) <- c("Low","Mod", "High")
LMH <- as.table(LMH)
LMH

tries=20
NMDS20=metaMDS(comm, k=2,try=tries)
treat=c(rep("Low",Low),rep("Moderate",Mod),rep("High",High))
ordiplot(NMDS20,type="n",choices=c(1,2),xaxt="n",yaxt="n", 
         xlab="nmds1",ylab="nmds2")
colors=c(rep("black",Low),rep("yellow",Mod),rep("red",High))
for(i in unique(treat)) {
        ordihull(NMDS20$point[grep(i,treat),],draw="polygon",
                 groups=treat[treat==i],col=colors[grep(i,treat)],label=F) } 
orditorp(NMDS20,col=c(rep("black",Low),rep("yellow",Mod),rep("red",High)),
         air=0.01,cex=1.25,display="species")
mtext(side=3, paste("20 DO", substitute(comm)) #This is where I want the title adjusted
mtext(side=1,"Stress =" )
mtext(side=1,padj=1, round(NMDS20$stress, 4))
}

makePlot(source = n20DO1, comm = bn20DO1)

One option is to place them in a list:

data = list(
a=matrix(1:10, ncol = 10,nrow=10),
b=matrix(11:20,ncol=10,nrow=10)
)

par(mfrow=c(1,2))
for(i in names(data)){
plot(data[[i]],xlab="x",ylab="y")
mtext(side=3, i)
}

enter image description here

Related