【问题标题】:How to maintain size of ggplot with long labels如何使用长标签保持 ggplot 的大小
【发布时间】:2017-05-24 22:01:44
【问题描述】:

我有一个图,它是每种事件类型的数量的简单条形图。我需要将情节的标签放在情节下方,因为某些事件的名称很长,并且正在横向挤压情节。我试图将标签移动到情节下方,但现在当有很多事件类型时,它会向上挤压。有没有办法获得静态图大小(即条形图),这样长图例就不会压扁图?

我的代码:

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)

结果:

我认为这是因为图像大小必须是静态的,因此会牺牲坐标轴的情节。当我在情节下方放置一个图例时,也会发生同样的事情。

【问题讨论】:

  • 如果有一个可重现的例子就好了:stackoverflow.com/questions/5963269/…
  • 至少剧情让我们能看懂?
  • @timat。我已经添加了情节
  • @SebastianZeki,当您导出情节时,请使用widthheigth 参数,这样上半部分就不是squas。您还可以将 x-label 角度更改为 60。将 x-label 对齐在左侧(勾选旁边),更改长标签,使其出现在 2 行上。这将减小 x-label 部分的大小。
  • egg::set_panel_size 可能有帮助

标签: r ggplot2


【解决方案1】:

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

虚拟数据

很遗憾,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")

OP 的方法:旋转标签

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

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

水平条形图

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

p + coord_flip()

带有标签的垂直条形图

标签直立打印,避免过度打印,减少打印区域的挤压。您可能不得不将width 参数设置为stringr::str_wrap

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

带标签的水平条形图

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

q + coord_flip()

附录:使用scale_x_discrete() 缩写标签

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

p + scale_x_discrete(labels = abbreviate)

【讨论】:

  • 很棒的答案。
  • 道歉投反对票,但这并不能回答问题,即如何实现“静态绘图大小(即条形图)”。这里提出的各种选项只是减轻了地块大小受标签长度影响的程度。地块大小将继续变化。如果无法在 ggplot2 中稳定绘图大小(相对于图像的整体尺寸),请在答案开头说出来,我会投票(假设是真的)。​​
  • @Uwe 您的回答对我来说非常有用,非常感谢!
【解决方案2】:

为了澄清,这个问题似乎要问的是如何在 ggplot2 中指定面板大小

我相信这个问题的正确答案是“你不能那样做”。

截至目前,似乎没有任何参数可以在任何 ggplot2 函数中设置来实现这一点。如果有的话,我认为它很可能是以 heightwidth 参数的形式在对 element_rect 的调用中调用 theme (这是我们对面板进行其他更改的方式,例如更改其背景颜色),但与 element_rect 的文档中的内容没有任何相似之处,所以我最好的猜测是指定面板大小是不可能的:

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

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

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

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

【讨论】:

  • 我在这里找到了解决方案:community.rstudio.com/t/…cowplot::align_plots 能够获取具有不同绘图/轴区域的绘图列表并将它们全部对齐以相同。还没有时间深入研究它是如何工作的,但是快速查看函数应该不难找出控制绘图/轴区域的参数。
【解决方案3】:

我发现其他方法并没有完全达到我想要的效果。我做了这个函数来在长名称后添加几个点


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.."


【讨论】:

    【解决方案4】:

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

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

    (使用@Uwe 的答案中的p 情节)

    【讨论】:

      猜你喜欢
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多