How to manipulate y-axis text labels in R varImpPlot? - r

The following sample resembles my dataset:
require(randomForest)
alpha = c(1,2,3,4,5,6)
bravo = c(2,3,4,5,6,7)
charlie = c(2,6,5,3,5,6)
mydata = data.frame(alpha,bravo,charlie)
myrf = randomForest(alpha~bravo+charlie, data = mydata, importance = TRUE)
varImpPlot(myrf, type = 2)
I cannot seem to control the placement of the y-axis labels in varImpPlot. I have tried altering the plot parameters (e.g. mar, oma), with no success. I need the y-axis labels shifted to the left in order to produce a PDF with proper label placement.
How can I shift the y-axis labels to the left?

I tried to use adj parameter but it produces a bug. As varImpPlot , use dotchart behind, Here a version using lattice dotplot. Then you can customize you axs using scales parameters.
imp <- importance(myref, class = NULL, scale = TRUE, type = 2)
dotplot(imp, scales=list(y =list(cex=2,
at = c(1,2),
col='red',
rot =20,
axs='i') ,
x =list(cex=2,col='blue')) )

You can extract the data needed to construct the plot out of myref and construct a plot with ggplot. By doing so you have more freedom in tweaking the plot. Here are some examples
library(ggplot2)
str(myrf)
str(myrf$importance)
data <- as.data.frame(cbind(rownames(myrf$importance),round(myrf$importance[,"IncNodePurity"],1)))
colnames(data) <- c("Parameters","IncNodePurity")
data$IncNodePurity <- as.numeric(as.character(data$IncNodePurity))
Standard plot:
(p <- ggplot(data) + geom_point(aes(IncNodePurity,Parameters)))
Rotate y-axis labels:
(p1 <- p+ theme(axis.text.y = element_text(angle = 90, hjust = 1)))
Some more tweaking (also first plot shown here):
(p2 <- p1 + scale_x_continuous(limits=c(3,7),breaks=3:7) + theme(axis.title.y = element_blank()))
Plot that looks like the varImpPlot (second plot shown here) :
(p3 <- p2+ theme(panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_line(colour = 'gray', linetype = 'dashed'),
panel.background = element_rect(fill='white', colour='black')))
Saving to pdf is easy with ggplot:
ggsave("randomforestplot.pdf",p2)
or
ggsave("randomforestplot.png",p2)
p2
p3

Did I understood correctly, that you want to get texts charlie and bravo more left of the boundary of the plot? If so, here's one hack to archive this, based on the modification of the rownames used in plotting:
myrf = randomForest(alpha~bravo+charlie, data = mydata, importance = TRUE)
#add white spaces at the end of the rownames
rownames(myrf$importance)<-paste(rownames(myrf$importance), " ")
varImpPlot(myrf, type = 2)
The adj parameter in dotchart is fixed as 0 (align to right), so that cannot be changed without modifying the code of dotchart:
mtext(labs, side = 2, line = loffset, at = y, **adj = 0**, col = color,
las = 2, cex = cex, ...)
(from dotchart)
EDIT:
You can make another type of hack also. Take the code of dotchart, change the above line to
mtext(labs, side = 2, line = loffset, at = y, adj = adjust_ylab, col = color,
las = 2, cex = cex, ...)
Then add argument adjust_ylab to the argument list, and rename the function as for example dotchartHack. Now copy the code of varImpPlot, find the line which calls dotchart, change the function name to dotchartHack and add the argument adjust_ylab=adjust_ylab to function call, rename the function to varImpPlotHack and add adjust_ylab to this functions argument list. Now you can change the alignment of the charlie and bravo by changing the parameter adjust_ylab:
myrf = randomForest(alpha~bravo+charlie, data = mydata, importance = TRUE)
varImpPlotHack(myrf, type = 2,adjust_ylab=0.5)
From ?par:
The value of adj determines the way in which text strings are
justified in text, mtext and title. A value of 0 produces
left-justified text, 0.5 (the default) centered text and
right-justified text. (Any value in [0, 1] is allowed, and on most
devices values outside that interval will also work.)

Related

Control Label of Contour Lines in `contour()`

I am using image() and contour() to create a "heatmap" of probabilities - for example:
I was asked to change the labels such that they "do not overlap the lines, and the lines are unbroken." After consulting ?contour(), I tried changing to method = "edge" and method = "simple", but both fail print the labels (although the lines are unbroken), and cant seem to find posts regarding similar issues elsewhere.
Any advice on how to manipulate the labels to appear adjacent to (not on top of) unbroken lines would be much appreciated. I would prefer base R but also would welcome options from more flexible packages or alternative base R functions.
Minimal code to recreate example figure is here:
# Generate Data
Rs <- seq(0.02, 1.0, 0.005)
ks <- 10 ^ seq(-2.3, 0.5, 0.005)
prob <- function(Y,R,k) {
exp(lgamma(k*Y+Y-1) - lgamma(k*Y) - lgamma(Y+1) + (Y-1) * log(R/k) - (k*Y+Y-1) * log(1+R/k))
}
P05 <- matrix(NA, ncol = length(ks), nrow = length(Rs))
for(i in 1:length(Rs)) {
for(j in 1:length(ks)) {
P05[i,j] <- 1 - sum(prob(1:(5 - 1), Rs[i], ks[j]))
}
}
colfunc <- colorRampPalette(c("grey25", "grey90"))
lbreaks <- c(-1e-10, 1e-5, 1e-3, 5e-3, 1e-2, 2e-2, 5e-2, 1e-1, 1.5e-1, 1)
## Create Figure
image(Rs, ks, P05,
log="y", col = rev(colfunc(length(lbreaks)-1)), breaks = lbreaks, zlim = lbreaks,
ylim = c(min(ks), 2), xlim = c(0,1))
contour(Rs, ks, P05, levels = lbreaks, labcex = 1, add = TRUE)
There is an easy(ish) way to do this in ggplot, using the geomtextpath package.
First, convert your matrix to an x, y, z data frame:
df <- expand.grid(Rs = Rs, ks = ks)
df$z <- c(P05)
Now plot a filled contour, and then geom_textcontour. By default the text will break the lines, as in contour, but if you set the vjust above one or below zero the lines will close up as they don't need to break for the text.
I've added a few theme and scale elements to match the aesthetic of the base graphics function. Note the text and line size, color etc remain independently adjustable.
library(geomtextpath)
ggplot(df, aes(Rs, ks, z = z)) +
geom_contour_filled(breaks = lbreaks) +
geom_textcontour(breaks = lbreaks, color = 'black', size = 5,
aes(label = stat(level)), vjust = 1.2) +
scale_y_log10(breaks = c(0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2),
expand = c(0, 0)) +
scale_fill_manual(values = rev(colfunc(9)), guide = 'none') +
scale_x_continuous(expand = c(0, 0)) +
theme_classic(base_size = 16) +
theme(axis.text.y = element_text(angle = 90, hjust = 0.5),
axis.ticks.length.y = unit(3, 'mm'),
plot.margin = margin(20, 20, 20, 20))
The contour function is mostly written in C, and as far as I can see, it doesn't support the kinds of labels you want.
So I think there are two ways to do this, neither of which is very appealing:
Modify the source to the function. You can see the start of the labelling code here. I think you would need to rebuild R to incorporate your changes; it's not easy to move a function from a base package to a contributed package.
Draw the plot with no labels, and add them manually after the fact. You could add them using text(), or produce an output file and use an external program to edit the output file.

R correlation plot using ggcorrplot2: "x-axis" labels get cropped

I am using ggcorrplot2 (github page) to generate my correlation plots, since I need to overlay significance levels as *** on top.
This package relies on ggplot2, so I thought it would be easy to change different features like axis label font size, asterisk color, gradient colors, etc. But it is proving to be more complicated than I thought.
My current problem at hand is that the "x-axis" labels get cropped out of the plotting area... As you see below, this isn't actually the x-axis, but rather labels placed on top of the diagonal cells. Hence, it is quite difficult to change them.
Check out this MWE. I first did this:
data(mtcars)
#change "wt" to a very long name
names(mtcars)[6] <- "a very long name"
corrtest <- psych::corr.test(mtcars[,1:7], adjust="none")
all_matrix <- corrtest$r
all_pmat <- corrtest$p
###
P <- ggcorrplot2::ggcorrplot(all_matrix, type = "lower", method = "circle", p.mat = all_pmat, show.diag = FALSE,
insig = "label_sig", sig.lvl = c(0.05, 0.01, 0.001), pch = "*", pch.cex = 6) +
ggplot2::theme(axis.text.y=ggplot2::element_text(size=15),
legend.text=ggplot2::element_text(size=15))
grDevices::pdf(file="heat_all2.pdf", height=6, width=6)
print(
P
)
grDevices::dev.off()
Which produces this:
As you can see, I was able to modify the y-axis labels with ggplot2 theme, but not the "x-axis" labels or anything else...
So I figured I could use ggplot_build and tweak the plot before actually printing it, and I did the following:
P <- ggcorrplot2::ggcorrplot(all_matrix, type = "lower", method = "circle", p.mat = all_pmat, show.diag = FALSE,
insig = "label_sig", sig.lvl = c(0.05, 0.01, 0.001), pch = "*", pch.cex = 6) +
ggplot2::theme(axis.text.y=ggplot2::element_text(size=15),
legend.text=ggplot2::element_text(size=15))
P2 <- ggplot2::ggplot_build(P)
P2$data[[4]]$size <- 5
P2$data[[4]]$hjust <- 0
P2$data[[3]]$angle <- 15
P2$data[[3]]$colour <- "grey30"
grDevices::pdf.options(reset = TRUE, onefile = FALSE)
grDevices::pdf(file="heat_all2.pdf", height=6, width=6)
print(
graphics::plot(ggplot2::ggplot_gtable(P2))
)
grDevices::dev.off()
Which produces this:
Very close, but still not quite there yet. The problems I keep encountering are the following:
The "x-axis" labels get cropped
Weird grey area on top and bottom of the plot
I want to change the color gradient so the darker blue and darker red
aren't that dark
I attempted to solve this by adding plot.margin=grid::unit(c(0,3,0,0),"cm") to theme, but the result is this (still cropped label and more grey space on top and bottom of the plot):
Any help? Thanks!
In the original function, the author set expand = c(0, 0) in scale_x_continuous(). You just need to modify that part to get what you want
library(tidyverse)
library(ggcorrplot2)
data(mtcars)
# change "wt" to a very long name
names(mtcars)[6] <- "a very long name"
corrtest <- psych::corr.test(mtcars[, 1:7], adjust = "none")
all_matrix <- corrtest$r
all_pmat <- corrtest$p
###
P <- ggcorrplot2::ggcorrplot(all_matrix,
type = "lower", method = "circle", p.mat = all_pmat, show.diag = FALSE,
insig = "label_sig", sig.lvl = c(0.05, 0.01, 0.001), pch = "*", pch.cex = 6) +
ggplot2::theme(axis.text.y = ggplot2::element_text(size = 15),
legend.text = ggplot2::element_text(size = 15))
P +
scale_x_continuous(expand = expansion(mult = c(0, 0.25)))
#> Scale for 'x' is already present. Adding another scale for 'x', which will
#> replace the existing scale.
Created on 2020-09-01 by the reprex package (v0.3.0)

How can I format the axes in plotRGB from the R raster package?

I'm trying to plot two plots side by side. One is a RasterStack for which I'm using plotRGB(). The axes are a mess however - it is plotting too many decimal places for the latitude and longitude. I'd also like to change the font size and text orientation.
This is straightforward in plot(), but I can't figure it out for plotRGB.
Can anyone help?
This is the code:
par(mar=c(4,5,4,2), mfrow = c(1, 2))
plotRGB(tayRGB, axes = TRUE, stretch = "lin", main = "RGB")
plot(knr, main = "Kmeans", cex.axis=0.96, col = viridis_pal(option="D")(10))
Can I recommend to use the function RStoolbox)::ggRGB instead of plotRGB. This will give you the full functionality of ggplot to customise your plot. A reproducible example:
set.seed(123)
R = raster(matrix(runif(400),20,20))
G = raster(matrix(runif(400),20,20))
B = raster(matrix(runif(400),20,20))
tayRGB = brick(list(R,G,B))
library(RStoolbox)
p1 = ggRGB(tayRGB, r=1, g=2, b=3, stretch = 'lin') +
scale_y_continuous(labels = scales::number_format(accuracy = 0.001)) +
scale_x_continuous(labels = scales::number_format(accuracy = 0.1)) +
theme(axis.title.x = element_text(size = 30),
axis.text.y = element_text(angle = 45))
p1
To plot your other plot side by side with this, you can either remake it as a ggplot. Or you can use ggplotify::base2grob to convert a base R plot into a grob.
p2 = ggplotify::base2grob(~plot(rnorm(100)))
cowplot::plot_grid(p1,p2)

Line break in R plot legend

I create many plots in R with data input from another script that are held in a separate variable each. I put the variables in a string and force a line break with \n. This works as intended, but the legend is not justified at all. xjust and yjust seem to not do anything. Also, when placing the legend e.g. in bottomright, it stretches beyond the margin of the plot. Any idea how I can properly place my legend justified at the corner of a plot?
Here a reproducible code snippet:
plot(c(0,3), c(0,3), type="n", xlab="x", ylab="y")
a <- 2.3456
b <- 3.4567
c <- 4.5678
d <- 5.6789
Corner_text <- function(text, location = "bottomright"){
legend(location, legend = text, bty = "o", pch = NA, cex = 0.5, xjust = 0)
}
Corner_text(sprintf("a = %3.2f m\n b = %3.2f N/m\UB2\n c = %3.2f deg\n d = %3.2f perc", a, b, c, d))
legend is usually used to explain what the points or lines (and the different colors) represent. Therefore, inside the legend box (bty) there is a space where the lines/points are supposed to be. This probably explains why you think your text is not left-justified (you also have a problem of space after your line-break (\n): if you put a space after a line-break, it will be your first character on the next line, hence the text does not appear justified).
In your example, you don't have lines or points to explain, hence, I would use text rather than legend.
To know where "bottomright" is on your axes, you can use the graphical parameters par("xaxp") and par("yaxp") (it gives you the values of first and last ticks and the number of ticks on your axis).
On the x-axis, from the last tick, you need to shift left to have space for the widest line.
In R code, it gives:
# your plot
plot(c(0,3), c(0,3), type="n", xlab="x", ylab="y")
# your string (without the extra spaces)
text_to_put <- sprintf("a = %3.2f m\nb = %3.2f N/m\UB2\nc = %3.2f deg\nd = %3.2f perc", a, b, c, d)
# the width of widest line
max_str <- max(strwidth(strsplit(text_to_put, "\n")[[1]]))
# put the text
text(x=par("xaxp")[2]-max_str, y=par("yaxp")[1], labels=text_to_put, adj=c(0, 0))
# if really you need the box (here par("usr") is used to know the extreme values on both axes)
x_offset <- par("xaxp")[1]-par("usr")[1]
y_offset <- par("yaxp")[1]-par("usr")[3]
segments(rep(par("xaxp")[2]-max_str-x_offset, 2), c(par("usr")[3], par("yaxp")[1]+strheight(text_to_put)+y_offset), c(par("xaxp")[2]-max_str-x_offset, par("usr")[2]), rep(par("yaxp")[1]+strheight(text_to_put)+y_offset, 2))
An example on how to do this using ggplot2, where legend creation is automatic when you map a variable in aes:
library(ggplot2)
units <- c('m', 'N/m\UB2', 'deg', 'perc')
p <- ggplot() + geom_hline(aes(yintercept = 1:4, color = letters[1:4])) + #simple example
scale_color_discrete(name = 'legend title',
breaks = letters[1:4],
labels = paste(letters[1:4], '=', c(a, b, c, d), units))
Or inside the plot:
p + theme(legend.position = c(1, 0), legend.justification = c(1, 0))
Or closer to your easthetic:
p + guides(col = guide_legend(keywidth = 0, override.aes = list(alpha = 0))) +
theme_bw() +
theme(legend.position = c(1, 0), legend.justification = c(1, 0),
legend.background = element_rect(colour = 'black'))

Manipulating axis titles in ggpairs (GGally)

I'm using the code below to generate the following chart.
# Setup
data(airquality)
# Device start
png(filename = "example.png", units = "cm", width = 20, height = 14, res = 300)
# Define chart
pairs.chrt <- ggpairs(airquality,
lower = list(continuous = "smooth"),
diag = list(continuous = "blank"),
upper = list(continuous = "blank")) +
theme(legend.position = "none",
panel.grid.major = element_blank(),
axis.ticks = element_blank(),
axis.title.x = element_text(angle = 180, vjust = 1, color = "black"),
panel.border = element_rect(fill = NA))
# Device off and print
print(pairs.chrt)
dev.off()
I'm currently trying to modify the display of the axis titles. In particular, I would like for the axis titles to be:
Placed at a further distance from axis labels
Placed at an angle
As an example, I would like to obtain axis titles similar to the ones pictured below (I'm interested in axis labels only, not in rest of the chart):
Taken from : Geovisualist
I' tried adjusting my syntax changing the axis.title.x to different values but it does not yield the desired results. For instance running the code with angle = 45.
axis.title.x = element_text(angle = 45, vjust = 1, color = "black"),
panel.border = element_rect(fill = NA))
returns the same chart. I was able to control the axis labels by changing the axis.text.x for instance but I can't find the answer how to control the axis titles in this plot. Any help will be much appreciated.
Short answer: There doesn't seem to be an elegant or easy way to do it, but here's a workaround.
I dug into the ggpairs source code (in the GGally package source available from CRAN) to see how the variable labels are actually drawn. The relevant function in ggpairs.R is print.ggpairs. It turns out the variable labels aren't part of the ggplot objects in each cell of the plot matrix -- i.e. they're not axis titles, which is why they aren't affected by using theme(axis.title.x = element_text(angle = 45) or similar.
Rather, they seem to be drawn as text annotations using grid.text (in package 'grid'). grid.text takes arguments including x, y, hjust, vjust, rot (where rot is angle of rotation), as well as font size, font family, etc. using gpar (see ?grid.text), but it looks like there is currently no way to pass in different values of those parameters to print.ggpairs -- they're fixed at default values.
You can work around it by leaving your variable labels blank to begin with, and then adding them on later with customized placement, rotation, and styling, using a modification of the relevant part of the print.ggpairs code. I came up with the following modification. (Incidentally, because the original GGally source code was released under a GPL-3 license, so is this modification.)
customize.labels <- function(
plotObj,
varLabels = NULL, #vector of variable labels
titleLabel = NULL, #string for title
leftWidthProportion = 0.2, #if you changed these from default...
bottomHeightProportion = 0.1, #when calling print(plotObj),...
spacingProportion = 0.03, #then change them the same way here so labels will line up with plot matrix.
left.opts = NULL, #see pattern in left.opts.default
bottom.opts = NULL, #see pattern in bottom.opts.default
title.opts = NULL) { #see pattern in title.opts.default
require('grid')
vplayout <- function(x, y) {
viewport(layout.pos.row = x, layout.pos.col = y)
}
numCol <- length(plotObj$columns)
if (is.null(varLabels)) {
varLabels <- colnames(plotObj$data)
#default to using the column names of the data
} else if (length(varLabels) != numCol){
stop('Length of varLabels must be equal to the number of columns')
}
#set defaults for left margin label style
left.opts.default <- list(x=0,
y=0.5,
rot=90,
just=c('centre', 'centre'), #first gives horizontal justification, second gives vertical
gp=list(fontsize=get.gpar('fontsize')))
#set defaults for bottom margin label style
bottom.opts.default <- list(x=0,
y=0.5,
rot=0,
just=c('centre', 'centre'),#first gives horizontal justification, second gives vertical
gp=list(fontsize=get.gpar('fontsize')))
#set defaults for title text style
title.opts.default <- list(x = 0.5,
y = 1,
just = c(.5,1),
gp=list(fontsize=15))
#if opts not provided, go with defaults
if (is.null(left.opts)) {
left.opts <- left.opts.default
} else{
not.given <- names(left.opts.default)[!names(left.opts.default) %in%
names(left.opts)]
if (length(not.given)>0){
left.opts[not.given] <- left.opts.default[not.given]
}
}
if (is.null(bottom.opts)) {
bottom.opts <- bottom.opts.default
} else{
not.given <- names(bottom.opts.default)[!names(bottom.opts.default) %in%
names(bottom.opts)]
if (length(not.given)>0){
bottom.opts[not.given] <- bottom.opts.default[not.given]
}
}
if (is.null(title.opts)) {
title.opts <- title.opts.default
} else{
not.given <- names(title.opts.default)[!names(title.opts.default) %in%
names(title.opts)]
if (length(not.given)>0){
title.opts[not.given] <- title.opts.default[not.given]
}
}
showLabels <- TRUE
viewPortWidths <- c(leftWidthProportion,
1,
rep(c(spacingProportion,1),
numCol - 1))
viewPortHeights <- c(rep(c(1,
spacingProportion),
numCol - 1),
1,
bottomHeightProportion)
viewPortCount <- length(viewPortWidths)
if(!is.null(titleLabel)){
pushViewport(viewport(height = unit(1,"npc") - unit(.4,"lines")))
do.call('grid.text', c(title.opts[names(title.opts)!='gp'],
list(label=titleLabel,
gp=do.call('gpar',
title.opts[['gp']]))))
popViewport()
}
# viewport for Left Names
pushViewport(viewport(width=unit(1, "npc") - unit(2,"lines"),
height=unit(1, "npc") - unit(3, "lines")))
## new for axis spacingProportion
pushViewport(viewport(layout = grid.layout(
viewPortCount, viewPortCount,
widths = viewPortWidths, heights = viewPortHeights
)))
# Left Side
for(i in 1:numCol){
do.call('grid.text',
c(left.opts[names(left.opts)!='gp'],
list(label=varLabels[i],
vp = vplayout(as.numeric(i) * 2 - 1 ,1),
gp=do.call('gpar',
left.opts[['gp']]))))
}
popViewport()# layout
popViewport()# spacing
# viewport for Bottom Names
pushViewport(viewport(width=unit(1, "npc") - unit(3,"lines"),
height=unit(1, "npc") - unit(2, "lines")))
## new for axis spacing
pushViewport(viewport(layout = grid.layout(
viewPortCount, viewPortCount,
widths = viewPortWidths, heights = viewPortHeights)))
# Bottom Side
for(i in 1:numCol){
do.call('grid.text',
c(bottom.opts[names(bottom.opts)!='gp'],
list(label=varLabels[i],
vp = vplayout(2*numCol, 2*i),
gp=do.call('gpar',
bottom.opts[['gp']]))))
}
popViewport() #layout
popViewport() #spacing
}
And here's an example of calling that function:
require('data.table')
require('GGally')
require('grid')
fake.data <- data.table(test.1=rnorm(50), #make some fake data for demonstration
test.2=rnorm(50),
test.3=rnorm(50),
test.4=rnorm(50))
g <- ggpairs(data=fake.data,
columnLabels=rep('', ncol(fake.data)))
#Set columnLabels to a vector of blank column labels
#so that original variable labels will be blank.
print(g)
customize.labels(plotObj=g,
titleLabel = 'Test plot', #string for title
left.opts = list(x=-0.5, #moves farther to the left, away from vertical axis
y=0.5, #centered with respect to vertical axis
just=c('center', 'center'),
rot=90,
gp=list(col='red',
fontface='italic',
fontsize=12)),
bottom.opts = list(x=0.5,
y=0,
rot=45, #angle the text at 45 degrees
just=c('center', 'top'),
gp=list(col='red',
fontface='bold',
fontsize=10)),
title.opts = list(gp=list(col='green',
fontface='bold.italic'))
)
(This makes some very ugly labels -- for the purposes of demonstration only!)
I didn't tinker with placing the labels somewhere other than the left and bottom -- as in your Geovisualist example -- but I think you'd do it by changing the arguments to vplayout in the "Left Side" and "Bottom Side" pieces of code in customize.labels. The x and y coordinates in grid.text are defined relative to a viewport, which divides the display area into a grid in
pushViewport(viewport(layout = grid.layout(
viewPortCount, viewPortCount,
widths = viewPortWidths, heights = viewPortHeights
)))
The call to vplayout specifies which cell of the grid is being used to position each label.
Caveat: not a complete answer but perhaps suggests a way to approach it. You can do this by editing the grid objects.
# Plot in current window
# use left to add space at y axis and bottom for below xaxis
# see ?print.ggpairs
print(pairs.chrt, left = 1, bottom = 1)
# Get list of grobs in current window and extract the axis labels
# note if you add a title this will add another text grob,
# so you will need to tweak this so not to extract it
g <- grid.ls(print=FALSE)
idx <- g$name[grep("text", g$name)]
# Rotate yaxis labels
# change the rot value to the angle you want
for(i in idx[1:6]) {
grid.edit(gPath(i), rot=0, hjust=0.25, gp = gpar(col="red"))
}
# Remove extra ones if you want
n <- ncol(airquality)
lapply(idx[c(1, 2*n)], grid.remove)
My answer won't fix the diagonal label issue but it will fix the overlay one.
I had this issue with the report I am currently writing, where the axis titles were always over the axes, especially in ggpairs. I used a combination of adjusting the out.height/out.width in conjunction with fig.height/fig.width. Separately the problem was not fixed, but together it was. fig.height/fig.width took the labels away from the axis but made them too small to read, and out.height/out.width just made the plot bigger with the problem unchanged. The below gave me the results shown:
out.height="400px", out.width="400px",fig.height=10,fig.width=10
before:plot with issues
after:

Resources