Search code examples
rggplot2text-alignmentsuperscript

Superscripted ggplot x-axis labels not aligning properly


I'm trying to add superscripted labels using either expression or bquote along the x-axis. The labels are a bit long and the space a bit tight, so I've placed it at a 45 degree angle, and broke it down with \n. When I add the labels without any superscripts it it correctly aligned to the right using hjust in axis.text.x. However, the moment I add in the supscript it only left aligns and I struggle to get it to correctly align with the x-axis, no matter what I settings I use for vjust and hjust. The example below is one of a few plots forming sections of a larger plot I'm putting together with ggarrange. Everything else works well, but because of the compact overall spacing I can't create more space within a single plot and keep the text horizontal.

The dataframe:

Example_Df <- data.frame(
  Treatment=factor(rep(c("Biochar25kgPha", "Biochar10tha", "Biochar10thaTSP", "Phosphorus"), each=4)),
  PO4=c(NA, 18.41, 21.64, 19.45, 13.05, 16.6, 19.22, 14.85, 10.92, 10.83, 18.6, 17.65, 12.14, 17.48, 19.15, 13.92),
  Precovery=c(-8.18, 14.53, -4.08, 0.23, 4.3, 1.79, -0.89, 2.88, -1.94, NA, -2.36, -0.81, -4.66, 4.56, 2.22, -5.8))
Example_Cor <- Example_Df%>%
  group_by(Treatment) %>%
  dplyr::summarize(Correlation = cor(Precovery, PO4, use = "complete.obs"))%>%
  ungroup()
Example_Cor$Treatment <- factor(Example_Cor$Treatment,
 levels=as.factor(c("Biochar25kgPha", "Biochar10tha", "Biochar10thaTSP", "Phosphorus")), 
 labels=as.character(c(expression(bold("Biochar\n25kg P ha"^-1)), expression(bold("Biochar\n10t ha"^-1)),
expression(bold("Biochar\n10t ha"^-1*" & TSP")), expression(bold("TSP\nFertilizer")))))

alternative setting of labels

Example_label <- as.character(list(expression(bold("Biochar\n25kg P ha"^-1)), expression(bold("Biochar\n10t ha"^-1)),
expression(bold("Biochar\n10t ha"^-1*" & TSP")), expression(bold("TSP\nFertilizer"))))

ggplot code:

ggplot(Example_Cor, aes(x=Treatment, y=0, fill=Correlation)) +
  geom_point(data=Example_Cor, aes(size=abs(Correlation)*20), shape=21) +
  scale_size(range = c(15, 30)) +
  scale_fill_viridis(option = "magma", limits=c(-1, 1), breaks=seq(-1, 1, by=0.5)) + 
  geom_text(aes(label=sprintf("%.2f", Correlation), color = ifelse(Correlation < 0, "white", "black")), size=5.5)+
  scale_color_manual(values=c("black", "white"), guide="none", labels=NULL)+
  labs(x="", y="", title=expression(bold("% P Recovery - Soil PO"[4])))+
  scale_x_discrete(labels=c(expression(bold("Biochar\n25kg P ha"^-1)), expression(bold("Biochar\n10t ha"^-1)),
                            expression(bold("Biochar\n10t ha"^-1*" & TSP")), expression(bold("TSP\nFertilizer"))))+
  guides(size = "none")+
  theme(plot.title = element_text(size=18, face="bold", hjust=0.5),
        legend.position = "none",
        axis.title=element_blank(),
        axis.text.y=element_blank(),
        axis.text.x=element_text(angle=45, size=16, colour="black", face="bold", hjust=0.95), # hjust setting doesn't change anything
        axis.ticks=element_blank(), panel.background=element_blank(),
        plot.margin=margin(15,5,5,15))

In scale_x_dixcrete I've tried setting scale_x_discrete(labels=Example_label) and labels=label_parsed, the latter both with Example_label and with Example_Df$Treatment but that only shows the labels exactly as they are written, not as they should appear. The only way I've found to get the notation right is to include the labels directly within ggplot, but then I can't get the alignment right. Hopefully the picture appears below. Plot example

Also, I would like there to be no space between the text and the ^-1 superscript. If the alignment issue will resolve this then great, but is there another way to do it? I've tried adding in * ^-1 * and wrapping the whole label in additional quotations without success.


Solution

  • Here's an approach using ggtext.

    library(ggtext)
    ggplot(Example_Cor, aes(x=Treatment, y=0, fill=Correlation)) +
      geom_point(data=Example_Cor, aes(size=abs(Correlation)*20), shape=21) +
      scale_size(range = c(15, 30)) +
      scale_fill_viridis_c(option = "magma", limits=c(-1, 1), breaks=seq(-1, 1, by=0.5)) + 
      geom_text(aes(label=sprintf("%.2f", Correlation), color = ifelse(Correlation < 0, "white", "black")), size=5.5)+
      scale_color_manual(values=c("black", "white"), guide="none", labels=NULL)+
      labs(x=NULL, y=NULL, title=expression(bold("% P Recovery - Soil PO"[4])))+
      scale_x_discrete(labels = c("Biochar<br>25kg P ha<sup>-1</sup>",
                                  "Biochar<br>10t ha<sup>-1</sup>",
                                  "Biochar<br>10t ha<sup>-1</sup>",
                                  "TSP<br>Fertilizer")) +
      guides(size = "none")+
      theme(plot.title = element_text(size=18, face="bold", hjust=0.5),
            legend.position = "none",
            axis.title=element_blank(),
            axis.text.y=element_blank(),
            axis.text.x = element_markdown(angle=45, size=16, colour="black", #debug = TRUE,
                                     face="bold", vjust = 1, hjust=1), # hjust setting doesn't change anything
            axis.ticks=element_blank(), panel.background=element_blank(),
            plot.margin=margin(15,5,5,15))
    

    enter image description here