5

I'm trying to make a correlation heatmap where the x axis is moved to the top using cowplot::switch_axis_position. I have axis labels of varying length and I want the labels to be left-aligned (or rather bottom-aligned, because they are rotated 90 degrees). Although I manage to align the labels, they are moved up far above the plot.

library(reshape2)
library(ggplot2)
library(cowplot)

# some toy data
set.seed(1)
mydata <- mtcars[, c(1, 3, 4, 5, 6, 7)]

# to show difference in justification better, make names of unequal length 
names(mydata) = paste0(sample(c("mtcars_", ""), 6, replace = TRUE), names(mydata))
cormat <- round(cor(mydata), 2)

melted_cormat <- melt(cormat)
head(melted_cormat)

First a plot where the x axis is moved to the top, and the labels are centered vertically:

plot <- ggplot(data = melted_cormat, aes(x=Var1, y=Var2, fill=value)) + 
        geom_tile() +
        theme_bw(base_size=20) + xlab("") + ylab("") +
        theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 0.5))
ggdraw(switch_axis_position(plot, 'x'))

link

Then I use the same code as above but with hjust = 0 instead to left-align the x axis text. It indeed aligns the text, but the text is moved weirdly far from graph so variable names are cut off: link

Any ideas of how to fix this?

Community
  • 1
  • 1
Esther
  • 441
  • 2
  • 15

1 Answers1

6

Please note: this bug is no longer present in the latest version of cowplot on CRAN.

Old answer:

It seems this is a bug for the special case of angle = 90. We can circumvent this by adding an arbitrarily small value to angle.

plot <- ggplot(data = melted_cormat, aes(x=Var1, y=Var2, fill=value)) + 
  geom_tile() + theme_bw(base_size=20) + xlab("") + ylab("")+
  theme(axis.text.x=element_text(angle=90 + 1e-09, hjust = 0, vjust=1)) +
  coord_equal(expand = 0)
ggdraw(switch_axis_position(plot, 'x'))

enter image description here

Community
  • 1
  • 1
Axeman
  • 32,068
  • 8
  • 81
  • 94
  • 1
    Nice. I had just finished my answer with padded_out column names and changing the font family to "mono".... but this is way better. – Mike Wise Feb 17 '16 at 18:48
  • 2
    Haha, not sure why this works though. I'm filing a github issue. – Axeman Feb 17 '16 at 18:49
  • You should file it as a bug, you can reference this post I think. – Mike Wise Feb 17 '16 at 18:49
  • thanks. that's odd. Is there a way to also get the labels centered on the tick mark? probably not? – Esther Feb 17 '16 at 18:58
  • You can play with `vjust` values slightly below 1 to get them closer, but it seems you'll have to trade off centering and distance from the axis. Quite unpredictable behavior indeed! – Axeman Feb 17 '16 at 19:02