如何用长标签维护ggplot的大小

时间:2017-01-10 12:02:42

标签: r ggplot2

我有一个情节,它是每种事件类型数量的简单条形图。我需要情节的标签在情节之下,因为一些事件有很长的名字并且正在横向挤压情节。我试图在标题下面移动标签,但是当有很多事件类型时,它现在会被压扁。有没有一种方法可以获得静态的地块大小(即条形图),以便长篇传说不会压缩情节?

我的代码:

ggplot(counts_df, aes(x = Var2, y = value, fill - Var1)+
    geom_bar(stat = "identity") +
    theme(legend.position = "bottom") +
    theme(legen.direction = "vertical") +
    theme(axis.text.x = element_text(angle = -90)

结果:

enter image description here

我认为这是因为图像尺寸必须是静态的,因此会牺牲轴的图形。当我在图中放置一个图例时,同样的事情发生了。

4 个答案:

答案 0 :(得分:25)

有几种方法可以避免标签过度绘图或挤压绘图区域或提高可读性。所提出的哪种解决方案最合适将取决于标签的长度和条的数量以及许多其他因素。所以,你可能不得不玩。

虚拟数据

不幸的是,OP没有包含可重复的示例,因此我们必须编制自己的数据:

V1 <- c("Long label", "Longer label", "An even longer label",
        "A very, very long label", "An extremely long label",
        "Long, longer, longest label of all possible labels", 
        "Another label", "Short", "Not so short label")
df <- data.frame(V1, V2 = nchar(V1))
yaxis_label <- "A rather long axis label of character counts"

“标准”条形图

x轴上的标签是直立打印的,相互重叠:

library(ggplot2)  # version 2.2.0+
p <- ggplot(df, aes(V1, V2)) + geom_col() + xlab(NULL) +
  ylab(yaxis_label) 
p

请注意,最近添加的geom_col()代替geom_bar(stat="identity")正在使用。

enter image description here

OP的方法:旋转标签

x轴上的标签旋转90°,挤压绘图区域:

p + theme(axis.text.x = element_text(angle = 90))

enter image description here

水平条形图

所有标签(包括y轴标签)都是直立打印的,提高了可读性,但仍然挤压了绘图区域(但在图表为横向格式时程度较小):

p + coord_flip()

enter image description here

带有标签的垂直条形图

标签直立打印,避免过度绘图,减少了绘图区域的挤压。您可能需要使用width参数来stringr::str_wrap

q <- p + aes(stringr::str_wrap(V1, 15), V2) + xlab(NULL) +
  ylab(yaxis_label)
q

enter image description here

包含标签的水平条形图

我最喜欢的方法:所有标签都是直立打印的,提高了可读性, 减少了对地块面积的挤压。同样,您可能需要使用width参数来stringr::str_wrap来控制标签分割的行数。

q + coord_flip()

enter image description here

附录:使用scale_x_discrete()

缩写标签

为了完整起见,应该提到ggplot2能够缩写标签。在这种情况下,我发现结果令人失望。

p + scale_x_discrete(labels = abbreviate)

enter image description here

答案 1 :(得分:2)

除上述解决方案之外的另一种解决方案 - 使用交错标签。这些可以与文本换行一起使用以获得相当可读的结果:

p + scale_x_discrete(guide = ggplot2::guide_axis(n.dodge = 2), 
                     labels = function(x) stringr::str_wrap(x, width = 20))

(使用来自@Uwe 答案的情节 p

enter image description here

答案 2 :(得分:1)

为澄清起见,这个问题似乎要问的是如何在ggplot2中指定面板尺寸

我相信这个问题的正确答案是“你就是做不到”。

到目前为止,似乎没有任何可以在实现该目标的ggplot2函数中设置的参数。如果有一个,我认为在调用height中,最有可能采用widthelement_rect参数的形式来调用theme(这是我们的方式)对面板进行其他更改(例如,更改其背景颜色),但是与element_rect的文档中没有类似的东西,所以我最好的猜测是指定面板尺寸是不可能的:

https://ggplot2.tidyverse.org/reference/element.html

以下参考文献很旧,但我找不到最新的资料来肯定地确认是否是这种情况:

https://groups.google.com/forum/#!topic/ggplot2/nbhph_arQ7E

在讨论中,有人问是否可以指定面板尺寸,哈德利说:“还没有,但是这是我的工作清单”。那是九年前;我想这仍然在他的待办事项清单上!

答案 3 :(得分:0)

我发现其他方法不能完全满足我的要求。我使用此功能在长名称后添加了两个点


tidy_name <- function(name, n_char) {
  ifelse(nchar(name) > (n_char - 2), 
    {substr(name, 1, n_char) %>% paste0(., "..")},
    name)
}

vec <- c("short", "medium string", "very long string which will be shortened")

vec %>% tidy_name(20)

# [1] "short"   "medium string"   "very long string whi.."