I’ve been trying for a while now to put the horizontal axis title on top of the chart after using coord_flip()
in ggplot2, but without any success.
I know I could:
- Set
scale_y_continuous (position = "right")
- Set
theme (axis.title.x.top = element_text (face = "bold"))
# I guess any format would do here, right?
But then:
- The whole axis would go to the top, and I want only the axis title there
- It doesn’t work, for some reason
CODE
example <- iris |>
ggplot (aes (x = reorder (Species, Petal.Width), y = Petal.Width)) +
geom_bar (stat = "identity", fill = "gray60") +
geom_hline (yintercept = 100 / nrow (iris), linetype = "dashed", color = "firebrick", size = 1) +
scale_y_continuous (limits = c(0, 15), breaks = seq (0, 15, 2.5), expand = c(0, 0)) +
coord_flip () +
labs (x = "", y = "Horizontal axis title") +
theme (axis.title = element_text (family = "MS", face = "bold", size = 18, color = "black"),
axis.text = element_text (family = "TNR", face = "plain", size = 16, color = "black"),
axis.text.x = element_text (angle = 45),
panel.background = element_rect (fill = NA),
panel.grid.major = element_line (color = "gray90"),
panel.grid.minor = element_line (color = "gray90"),
plot.margin = margin (t = 20, r = 20, b = 5, l = 5)) +
windows (); example
I’d defer to @stefan’s solution for splitting up the axis title and the breaks; that is simplest with a duplicate axis.
I would add, though, that most cases to use coord_flip()
were eliminated with ggplot2 3.3.0 in 2020. (Though occasionally you may need to add the orientation
parameter if the aesthetics don’t make it clear).
Then we can do:
iris |>
ggplot(aes(y = reorder (Species, Petal.Width), x = Petal.Width)) +
geom_col(fill = "gray60") +
geom_vline(xintercept = 100 / nrow (iris), linetype = "dashed",
color = "firebrick", size = 1) +
scale_x_continuous(limits = c(0, 15), breaks = seq (0, 15, 2.5),
expand = c(0, 0), name = NULL,
sec.axis = dup_axis(breaks = NULL, name = "Horizontal axis title")) +
labs(y = NULL) # avoids even having a space for the axis title
1
One option would be to use a secondary axis for which you remove the axis text and ticks using e.g. breaks=NULL
and getting rid of the primary axis title:
library(ggplot2)
iris |>
ggplot(aes(x = reorder(Species, Petal.Width), y = Petal.Width)) +
geom_bar(stat = "identity", fill = "gray60") +
geom_hline(
yintercept = 100 / nrow(iris), linetype = "dashed",
color = "firebrick", size = 1
) +
scale_y_continuous(
limits = c(0, 15), breaks = seq(0, 15, 2.5), expand = c(0, 0),
sec.axis = dup_axis(breaks = NULL, name = "Horizontal axis title")
) +
coord_flip() +
labs(x = "", y = NULL) +
theme(
axis.title = element_text(face = "bold", size = 18, color = "black"),
axis.text = element_text(face = "plain", size = 16, color = "black"),
axis.text.x = element_text(angle = 45),
panel.background = element_rect(fill = NA),
panel.grid.major = element_line(color = "gray90"),
panel.grid.minor = element_line(color = "gray90"),
plot.margin = margin(t = 20, r = 20, b = 5, l = 5)
)
#> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
#> ℹ Please use `linewidth` instead.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.
#> Warning: Removed 82 rows containing missing values or values outside the scale range
#> (`geom_bar()`).