How to auto adjust R figure axis labels to matrix size?

夙愿已清 提交于 2020-01-23 12:23:30

问题


I want to make the fontsize of the y-axis labels adjustable to the input data size on the y-axis like in Fig. 3, in contrast to the current situation in Fig. 1-2 where labels are not next to the corresponding lines. Code

library("corrgram")

# https://stackoverflow.com/a/40387233/54964
ids <- seq(1,18)
x_at <- seq(0.075, 0.925, length.out = length(ids))
y_at <- seq(0.075, 0.91, length.out = length(ids))

createLabels <- function(xlab, ylab, x_labels, y_labels){
ids <- y_labels # assume here
x_at <- seq(0.075, 0.925, length.out = length(ids))
y_at <- seq(0.075, 0.91, length.out = length(ids))
mtext(xlab, side = 1, line = 4)
mtext(ylab, side = 2, line = 3)
axis(1, at=x_at, labels=x_labels, line = 1.5, tick=F, cex.axis=.7)
axis(2, at=y_at, labels=y_labels, line = 1, tick=F, cex.axis=.7, las=1) # horizontal y-axis labels; rawr
}

corrgram(baseball,main="Baseball data PC2/PC1 order")
createLabels(xlab="Patient 1 ID", ylab="Patient 2 ID", x_labels=ids, y_labels=ids)

Fig. 1 Output with the limited test data baseball, Fig. 2 Output with the real case, Fig. 3 Expected output

Expected output: automatically adjustable label font size to the input data size on the y-axis; example of the output created by makeMatrixPlot(list, ids, title) found here in Fig. 3

Testing Istrel's answer with big data set where long IDs

Complete code here which visualises correctly but gives backside strange outputs an NULLs, here some key points about optimised parameters

# https://stackoverflow.com/a/40485734/54964
cex_lab<-0.9 # little smaller fontsize for matrix >= 20x20
oma<-c(4, 4, 6, 4)
gap<-0
las<-2 # both axis labels always perpendicular

Output complications as the warning and many NULLs

In max(l.wid) : no non-missing arguments to max; returning -Inf
[[1]]
[[1]][[1]]
NULL
...
[[1]][[7]]
NULL


[[2]]
[[2]][[1]]
NULL
...    
[[2]][[7]]
NULL


[[3]]
[[3]][[1]]
NULL
...  
[[3]][[7]]
NULL

Call it for instance by

library("corrplot")
library("psych")

ids <- seq(1,11) 

M.cor <- cor(mtcars)
colnames(M.cor) <- ids
rownames(M.cor) <- ids

p.mat <- psych::corr.test(M.cor, adjust = "none", ci = F)
p.mat <- p.mat[["r"]]

corrplot(M.cor, 
  method = "color", 
  type = "upper", 
  tl.col = 'black', 
  diag = TRUE, 
  p.mat = p.mat, 
  sig.level = 0.0000005
)

createLabels(xlab="Patient 1 ID", ylab="Patient 2 ID and Ages", x_labels=ids, y_labels="") 

R: 3.3.1
Used graphic objects: corrplot, corrgram, ...
OS: Debian 8.5


回答1:


The corrgram package has been updated (version 1.11) with better support for labels along the axes. I've used the basic idea from Leo and added it to the package. For example:

require(corrgram)
labs=colnames(state.x77)
corrgram(state.x77, oma=c(7, 7, 2, 2),
         outer.labels=list(bottom=list(labels=labs,cex=1.5,srt=60),
                           left=list(labels=labs,cex=1.5,srt=30)))
mtext("Bottom", side=1, cex=2, line = -1.5, outer=TRUE, xpd=NA)
mtext("Left", side=2, cex=2, line = -1.5, outer=TRUE, xpd=NA)




回答2:


Corrgram uses mfrow from par() for squares drawing. We can use that for labeling. The number of labels should be equal to the number of columns in the matrix. If you set oma or gap arguments in corrgram function, you have to specify same parameters in createLabels function.

BTW, if you use corrgram without main argument, you will need oma=c(4,4,4,4) in createLabels

createLabels <- function(xlab, ylab, x_labels, y_labels, 
                cex_lab=1.3, oma=c(4, 4, 6, 4), gap=0, las=0){
# oma and gap args same as in corrgram
nc <- length(x_labels) # get number of columns

# Inititate mfrow partition as in corrgram
opar <- par(mfrow = c(nc, nc), mar = rep.int(gap/2, 4), oma = oma) #save old par parameters

# Create matrix of outer cells indexes and positions
left_side <- matrix(c(nc:1, rep(1, nc), rep(2, nc)), nc)
bottom_side <- matrix(c(rep(nc, nc), 1:nc, rep(1, nc)), nc)
sides <- rbind(left_side, bottom_side)


# Dublicate labels vector
labels <- c(y_labels, x_labels)

# Loop over each outer cell
for (i in c(1:(nc*2))){
    cell_ind <- sides[i, ]
    par(mfg=c(cell_ind[1], cell_ind[2], nc, nc)) # set current plotting cell
    usr<-par("usr")
    clip(usr[1], -2, usr[3], usr[4]) # alter clipping region
    axis(cell_ind[3], at=0.5, labels=labels[i], 
        outer=TRUE, xpd=NA, lwd=NA, mgp=c(3,0,0.2), cex.axis=cex_lab, las=las)
}

# Add labels
par(opar)
mtext(xlab, side = 1, line = -1.5, outer=TRUE, xpd=NA)
mtext(ylab, side = 2, line = -1.5, outer=TRUE, xpd=NA)
}

corrgram(baseball,main="Baseball data PC2/PC1 order")
createLabels(xlab="Patient 1 ID", ylab="Patient 2 ID", 1:18, 1:18)



来源:https://stackoverflow.com/questions/40436727/how-to-auto-adjust-r-figure-axis-labels-to-matrix-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!