【问题标题】:How to alternate a new line for overlapping x axis labels?如何为重叠的 x 轴标签交替换行?
【发布时间】:2018-05-17 20:13:41
【问题描述】:

在 x 轴上绘制长文本因子时,ggplot 效果不佳。我想换一个新行,这样更清晰(所以下图中的红色标记应该是一行)。

我在comments here 中找到了答案,但无法正常工作。代码是:

scale_x_discrete( labels = function( labels ) { 
fixedLabels <- c() for ( l in 1:length( labels ) ) { 
fixedLabels <- c( fixedLabels, paste0( ifelse( l %% 2 == 0, '', '\n' ), labels[l] ) ) } return( fixedLabels ) } )

测试数据:

library(ggplot2)

Group = c("D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10", "D11", "D12", "D13", "D14")
x = c(141, 57, 38, 18, 13, 7, 5, 4, 2, 2, 1, 1, 1, 1)

dat <- data.frame(
  Group = Group,
  x = x,
  stringsAsFactors=TRUE
)

dat <- dat[order(dat$x, decreasing=TRUE), ]
dat$Group <- factor(dat$Group, levels=dat$Group[order(dat$x, decreasing=TRUE)])
cum = sum(dat$x)
dat$cum <- 100*(dat$x)/cum
dat$cum = cumsum(dat$cum)

> dat
   Group   x       cum
1     D1 141  48.45361
2     D2  57  68.04124
3     D3  38  81.09966
4     D4  18  87.28522
5     D5  13  91.75258
6     D6   7  94.15808
7     D7   5  95.87629
8     D8   4  97.25086
9     D9   2  97.93814
10   D10   2  98.62543
11   D11   1  98.96907
12   D12   1  99.31271
13   D13   1  99.65636
14   D14   1 100.00000

 ggplot(dat, aes(x=Group)) +
  geom_bar(aes(y=x), fill="light blue", stat="identity") +
  stat_count(aes(label = x), geom = "text", vjust=-0.3, size=3.5) + 
  geom_point(aes(y=cum)) +
  geom_path(aes(y=cum, group=1))

【问题讨论】:

  • 将绘图旋转 90 度是另一种处理长轴标签的方法。使用 ggplot2,您可以添加 + coord_flip() 来旋转绘图。 ggstance 包还具有用于水平图的几何图形(例如,geom_barh)。如果你想要值标签,你可以把它们放在零以下,这样标签就不会干扰条形高度到幅度的视觉映射。

标签: r ggplot2


【解决方案1】:

ggplot2 3.3.2 开始,您可以简单地使用scale_x_discrete(guide = guide_axis(n.dodge = 2))。这在release notes 中进行了讨论。

library(ggplot2)

p <- ggplot(mpg) +
  geom_bar(aes(x = manufacturer)) + 
  scale_x_discrete(guide = guide_axis(n.dodge = 2))
p

reprex package (v1.0.0) 于 2021-04-14 创建

【讨论】:

    【解决方案2】:

    这是您在 cmets 中发现的一个巧妙的小技巧!它确实有效,只要确保你注意你的语法:l != 1 虽然它看起来非常相似:

    ggplot(dat, aes(x = Group)) +
      geom_bar(aes(y = x), fill = "light blue", stat = "identity") +
      stat_count(aes(label = x), geom = "text", vjust = -0.3, size = 3.5) + 
      geom_point(aes(y = cum)) +
      geom_path(aes(y = cum, group = 1)) +
      scale_x_discrete(labels = function(labels) {
        fixedLabels <- c()
        for (l in 1:length(labels)) {
          fixedLabels[l] <- paste0(ifelse(l %% 2 == 0, '', '\n'), labels[l])
        }
        return(fixedLabels)
      })
    

    注意:您可以选择更简洁地重写语法(这里我使用i 以避免混淆并可能使其更具可读性):

    ggplot(dat, aes(x = Group)) +
      geom_bar(aes(y = x), fill = "light blue", stat = "identity") +
      stat_count(aes(label = x), geom = "text", vjust = -0.3, size = 3.5) + 
      geom_point(aes(y = cum)) +
      geom_path(aes(y = cum, group = 1)) +
      scale_x_discrete(labels = function(labels) {
        sapply(seq_along(labels), function(i) paste0(ifelse(i %% 2 == 0, '', '\n'), labels[i]))
      })
    

    【讨论】:

    • 效果很好。抱歉,星期五接受晚了:P
    【解决方案3】:

    不是您要的,但处理长轴标签的另一种好方法是将它们以 45* 角放置:

    Group = c("LongerNameD1", "LongerNameD2", "LongerNameD3", "LongerNameD4", "LongerNameD5", "LongerNameD6", "LongerNameD7", "LongerNameD8", "LongerNameD9", "LongerNameD10", "LongerNameD11", "LongerNameD12", "LongerNameD13", "LongerNameD14")
    x = c(141, 57, 38, 18, 13, 7, 5, 4, 2, 2, 1, 1, 1, 1)
    
    dat <- data.frame(
         Group = Group,
         x = x,
         stringsAsFactors=TRUE
    )
    
    dat <- dat[order(dat$x, decreasing=TRUE), ]
    dat$Group <- factor(dat$Group, levels=dat$Group[order(dat$x, decreasing=TRUE)])
    cum = sum(dat$x)
    dat$cum <- 100*(dat$x)/cum
    dat$cum = cumsum(dat$cum)
    
    
    ggplot(dat, aes(x = Group)) +
         geom_bar(aes(y = x), fill = "light blue", stat = "identity") +
         stat_count(aes(label = x), geom = "text", vjust = -0.3, size = 3.5) + 
         geom_point(aes(y = cum)) +
         geom_path(aes(y = cum, group = 1))+
         theme(axis.text.x  = element_text(angle=45, hjust = 1))
    

    【讨论】:

    • 非常感谢您的意见,我会试试的,看起来棒极了!
    猜你喜欢
    • 1970-01-01
    • 2012-11-11
    • 2014-04-30
    • 2017-07-20
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多