How to add subtext to axes in ggplot2 R
Asked Answered
S

3

8

For the main y-axis and x-axis, I have generic titles like "Tank's Ratio" and "Counts". I want a second line of label where I specify the ratio and counts. eg. Just below "Tank's Ratio" I want "# in water/# in sand" in a smaller font but along the y-axis. Similarly for the x-axis. Here is the basic code

data <- data.frame(set = c(1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4), density = c(1, 3, 3, 1, 3, 1, 1, 1, 3, 3, 1, 3), counts = c(100, 2, 3, 76, 33, 12, 44, 13, 54, 36, 65, 1), ratio = c(1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 90, 1))

library(ggplot2)

ggplot(data, aes(x = counts, y = ratio)) + 
  geom_point() + 
  ylab("Tank's Ratio") + 
  xlab("Counts") 
Settee answered 8/1, 2019 at 13:51 Comment(1)
I'm not sure about resizing the font, but you can add a newline character (\n) to the ylab. Try ggplot(data,aes(x=counts, y=ratio)) + geom_point() +ylab("Tank's Ratio \n#in water/# in sand") + xlab("Counts") Chucklehead
P
2

It's not the most elegant solution, but hope it helps:

library(ggplot2)
library(gridExtra)
library(grid)

First, create plot without ylab:

g <- ggplot(data, aes(x = counts, y = ratio)) + 
  geom_point()  +
  ylab("") + 
  xlab("Counts") 

Then add subtitle for both axis:

g2 <- grid.arrange(g, 
                   bottom = textGrob("in water/ # in sand", 
                                     x = 0.55, y = 1, gp = gpar(fontsize = 9)),
                   left = textGrob("in water/ # in sand",  rot = 90, 
                                   x = 1.5, gp = gpar(fontsize = 9)))

And finally, add description of y-axis

grid.arrange(g2, 
             left = textGrob("Tank's Ratio",  rot = 90, 
                             x = 1.7, gp = gpar(fontsize = 12)))

enter image description here

Potash answered 8/1, 2019 at 14:21 Comment(0)
H
3

You can add x and main titles.

EDIT: This is ridiculously slooow!

  #library(extrafont)
#loadfonts(dev="win")
library(tidyverse)
data %>%
ggplot(aes(x=counts, y=ratio)) + geom_point() +
labs(y=expression(atop(bold("Tank's Ratio"),atop(italic("#in water #in sand")))))+
  theme_minimal()+
  theme(axis.title.y = element_text(size=15,family="Comic Sans MS"))

enter image description here

ORIGINAL:

library(tidyverse) 

      data %>%
    ggplot(aes(x=counts, y=ratio)) + geom_point() +
    labs(y="Tank's Ratio \n #in Water#in sand")
Halfcaste answered 8/1, 2019 at 14:25 Comment(2)
This doesn't use smaller font size as OP wanted.Disoperation
Edited but I think it's too slow.Halfcaste
P
2

It's not the most elegant solution, but hope it helps:

library(ggplot2)
library(gridExtra)
library(grid)

First, create plot without ylab:

g <- ggplot(data, aes(x = counts, y = ratio)) + 
  geom_point()  +
  ylab("") + 
  xlab("Counts") 

Then add subtitle for both axis:

g2 <- grid.arrange(g, 
                   bottom = textGrob("in water/ # in sand", 
                                     x = 0.55, y = 1, gp = gpar(fontsize = 9)),
                   left = textGrob("in water/ # in sand",  rot = 90, 
                                   x = 1.5, gp = gpar(fontsize = 9)))

And finally, add description of y-axis

grid.arrange(g2, 
             left = textGrob("Tank's Ratio",  rot = 90, 
                             x = 1.7, gp = gpar(fontsize = 12)))

enter image description here

Potash answered 8/1, 2019 at 14:21 Comment(0)
S
2

You could use the following code, defining the margins, the axis titles and sub-titles yourself:

We use theme to increase the bottom and left margin, and to suppress the automatically generated axis titles.

We use annotate to generate the text that serves as axis title and sub-title, if necessary, the text is rotated.

We generate the plot, turn it in a grob, and with this grob we can turn of clipping, and show the plot.

g1 <- ggplot(data = data, aes(x = counts, y = ratio, group = 1)) +
  geom_point()  + 

  ## increase margin size for left and bottom and
  ## remove the axis titles
  theme(plot.margin = unit(c(1, 1, 4, 4), "lines"),
        axis.title.y = element_blank(),
        axis.title.x = element_blank() ) +

  ## define the plotting area to NOT include the annotations
  coord_cartesian(xlim = c(0, 100), ylim= c(0, 100), expand = FALSE) +

  ## annotate y axis
  annotate(geom = "text", x = -9, y = 50, label = "Tank's Ratio", angle = 90, size = 5) +
  annotate(geom = "text", x = -5, y = 50, label = "#in water/#in sand", angle = 90, size = 4) +

  ## annotate x axis
  annotate(geom = "text", x = 50, y = -5, label = "Counts", size = 5) +
  annotate(geom = "text", x = 50, y = -9, label = "#in water/#in sand", size = 4)

## turn off  clipping for axis extra labels
g2 <- ggplot_gtable(ggplot_build(g1))
g2$layout$clip[g2$layout$name == "panel"] <- "off"
grid::grid.draw(g2)

This yields the following picture:

enter image description here

Please let me know whether this is what you want.

Sweeting answered 8/1, 2019 at 15:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.