问题描述
我正在尝试实现一种包装x轴标签的解决方案,以使它们不会重叠.我知道这个问题已经问过几次了,并且有(v0.3.0)创建于2021-01-29
2.当我们使用 ggfittext
时,我们可以看到条形内的标签如何缩小以适合条形
库(tidyverse)库(ggfittext)#>警告:软件包"ggfittext"是在R版本4.0.3下构建的my_mtcars<-mtcars [15:20,]%&%;%rownames_to_column(汽车")my_mtcars%>%ggplot(aes(x =汽车,y = mpg,填充=汽车))+geom_bar(stat ="identity")+geom_bar_text(aes(label = cars),颜色=蓝色",调整= 1,大小= 7 * ggplot2 ::.pt,最小尺寸= 0,padding.x = grid :: unit(0,"pt"),padding.y = grid :: unit(0,"pt"))#>警告:忽略未知的美学:标签
我的问题
我不知道该怎么做,但是我们可以通过某种方式让 ggfittext
为我们完成艰苦的工作来动态地包装/调整大小/缩放x轴标签吗?以我天真的方式看,条形图内的文本已经被正确渲染了,我们可以复制"图样吗?这样以某种方式渲染到轴标签?
我们如何将 ggfittext
文本放在y轴下方?我们关闭裁剪,并设置 oob
和 limits
以适合我们的数据.应该调整 axis.text.x
的大小,使其与x轴标题更好地对齐.
库(tidyverse)#>警告:软件包"tidyr"是在R版本4.0.3下构建的#>警告:软件包"readr"是在R版本4.0.3下构建的#>警告:软件包"dplyr"是在R版本4.0.3下构建的库(ggfittext)#>警告:软件包"ggfittext"是在R版本4.0.3下构建的my_mtcars<-mtcars [15:20,]%&%;%rownames_to_column(汽车")my_mtcars%>%ggplot(aes(x =汽车,y = mpg,填充=汽车))+geom_bar(stat ="identity")+geom_fit_text(aes(label = cars,y = -4),回流= TRUE,高度= 50,show.legend = FALSE)+scale_y_continuous(oob = scales :: oob_keep,限制= c(0,NA))+coord_cartesian(clip ="off")+主题(axis.text.x = element_text(colour ="transparent",大小= 18))
从标签中删除标签
库(tidyverse)库(ggfittext)my_mtcars<-mtcars [15:20,]%&%;%rownames_to_column(汽车")p<-my_mtcars%>%ggplot(aes(x =汽车,y = mpg,填充=汽车))+geom_bar(stat ="identity")+geom_fit_text(aes(label = cars,y = -1),回流= TRUE,高度= 50,show.legend = FALSE)+scale_y_continuous(oob = scales :: oob_keep,限制= c(0,NA))+coord_cartesian(clip ="off")+主题(axis.text.x = element_text(colour ="transparent",大小= 18))grob<-grid :: makeContent(layer_grob(p,2)[[1]])$ children大小<-vapply(grob,function(x){x $ gp $ fontsize},numeric(1))标签<-unname(vapply(grob,function(x){x $ label},character(1)))打印(标签)#>[1]凯迪拉克\弗里特伍德"林肯\大陆"克莱斯勒\帝国"#>[4]菲亚特128"本田思域"丰田\ n花冠"
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")
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
3. ggtext
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
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?
How about we just place the ggfittext
text below the y-axis? We turn off clipping and set the oob
and limits
to suit our data. Should probably tweak the axis.text.x
size to align better with the x-axis title.
library(tidyverse)
#> Warning: package 'tidyr' was built under R version 4.0.3
#> Warning: package 'readr' was built under R version 4.0.3
#> Warning: package 'dplyr' was built under R version 4.0.3
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_fit_text(aes(label = cars, y = -4),
reflow = TRUE, height = 50,
show.legend = FALSE) +
scale_y_continuous(oob = scales::oob_keep,
limits = c(0, NA)) +
coord_cartesian(clip = "off") +
theme(axis.text.x = element_text(colour = "transparent", size = 18))
EDIT: Getting the labels out of the grob
library(tidyverse)
library(ggfittext)
my_mtcars <-
mtcars[15:20,] %>%
rownames_to_column("cars")
p <- my_mtcars %>%
ggplot(aes(x = cars, y = mpg, fill = cars)) +
geom_bar(stat = "identity") +
geom_fit_text(aes(label = cars, y = -1),
reflow = TRUE, height = 50,
show.legend = FALSE) +
scale_y_continuous(oob = scales::oob_keep,
limits = c(0, NA)) +
coord_cartesian(clip = "off") +
theme(axis.text.x = element_text(colour = "transparent", size = 18))
grob <- grid::makeContent(layer_grob(p, 2)[[1]])$children
sizes <- vapply(grob, function(x){x$gp$fontsize}, numeric(1))
labels <- unname(vapply(grob, function(x){x$label}, character(1)))
print(labels)
#> [1] "Cadillac\nFleetwood" "Lincoln\nContinental" "Chrysler\nImperial"
#> [4] "Fiat 128" "Honda Civic" "Toyota\nCorolla"
这篇关于ggplot2:如何动态包装/调整/调整x轴标签的大小,以便它们不会重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!