I'm trying to achieve a solution for wrapping x axis labels so they won't overlap. I know this question has been asked several times, and that there are some good answers. However, no solution that I've seen answers how to re-wrap the labels as the plot gets resized.
Three different answers at SO make me believe this could be attainable.
This solution wrote a custom-made
geom
for fitting the bar's labelsize
to fit within the bar's width, dynamically as you resize the plot.This solution relies on an extension package for
ggplot2
calledggtext
. The solution allows dynamic word wrapping of the plot's title, as you resize the plot, based on creating aelement_textbox()
.This solution relies on another extension called
ggfittext
. It shows how thesize
of the label inside the bar can vary dynamically to fit the bar's dimensions as you resize the plot. Essentially, it addresses the same problem as solution (1) above, but is much more powerful. In fact, and this is the feature that makes me hopeful, it relies on a general solutiongeom_fit_text()
to fit text inside rectangles, not justgeom_bar()
s.
Some demo data to work with
1. Just to show the typical output when x axis labels are overlapping
library(tidyverse)
my_mtcars <-
mtcars[15:20,] %>%
rownames_to_column("cars")
my_mtcars %>%
ggplot(aes(x = cars, y = mpg, fill = cars)) +
geom_bar(stat = "identity")
Created on 2021-01-29 by the reprex package (v0.3.0)
2. When we use ggfittext
we can see how labels inside the bars shrink in size to fit the bar
library(tidyverse)
library(ggfittext)
#> Warning: package 'ggfittext' was built under R version 4.0.3
my_mtcars <-
mtcars[15:20,] %>%
rownames_to_column("cars")
my_mtcars %>%
ggplot(aes(x = cars, y = mpg, fill = cars)) +
geom_bar(stat = "identity") +
geom_bar_text(aes(label = cars),
color = "blue",
vjust = 1,
size = 7 * ggplot2::.pt,
min.size = 0,
padding.x = grid::unit(0, "pt"),
padding.y = grid::unit(0, "pt"))
#> Warning: Ignoring unknown aesthetics: label
Created on 2021-01-29 by the reprex package (v0.3.0)
3. ggfittext
has the reflow
argument that promotes text wrapping
library(tidyverse)
library(ggfittext)
#> Warning: package 'ggfittext' was built under R version 4.0.3
my_mtcars <-
mtcars[15:20,] %>%
rownames_to_column("cars")
my_mtcars %>%
ggplot(aes(x = cars, y = mpg, fill = cars)) +
geom_bar(stat = "identity") +
geom_bar_text(aes(label = cars),
color = "blue",
vjust = 1,
size = 7 * ggplot2::.pt,
min.size = 0,
padding.x = grid::unit(0, "pt"),
padding.y = grid::unit(0, "pt"),
reflow = TRUE ## <--------------- added this
)
#> Warning: Ignoring unknown aesthetics: label
Created on 2021-01-29 by the reprex package (v0.3.0)
My question
I don't know how to do it, but could we get x axis labels wrapped/resized/rescaled dynamically, by somehow letting ggfittext
do the hard work for us? In the naïve way I see this, the text within the bars is already rendered the right way, can we just "copy" this rendering somehow to the axis labels?