【问题标题】:overlay barplot with line: shifted y-axis用线覆盖条形图:移动 y 轴
【发布时间】:2017-05-09 23:16:51
【问题描述】:

数据:

V   D1  D2  D3  CS1 CS2 CS3
10  2038    1806    1643    72.81171847 64.52304394 58.69953555
20  550 709 757 92.46159343 89.85351911 85.7449089
30  142 192 271 97.53483387 96.71311183 95.42693819
40  45  61  80  99.14255091 98.89246159 98.28510182
50  12  20  30  99.57127546 99.6070025  99.35691318
60  5   6   10  99.74991068 99.82136477 99.71418364
70  2   2   3   99.82136477 99.89281886 99.82136477
80  4   1   2   99.96427295 99.92854591 99.89281886
90  1   0   1   100.0000000 99.92854591 99.92854591
100 0   1   0   100.0000000 99.96427295 99.92854591

脚本:

mp<-barplot(as.matrix(t(df[,2:4])),beside=TRUE,xlim=c(0,40),ann=FALSE)
mp
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]  1.5  5.5  9.5 13.5 17.5 21.5 25.5 29.5 33.5  37.5
[2,]  2.5  6.5 10.5 14.5 18.5 22.5 26.5 30.5 34.5  38.5
[3,]  3.5  7.5 11.5 15.5 19.5 23.5 27.5 31.5 35.5  39.5

par(new=TRUE)
plot(mp[2,],df$CS1,xlim=c(0,40),type="l",col="red",axes=FALSE,ylim=c(0,100),ann=FALSE)
lines(mp[2,],df$CS2,col="blue")
lines(mp[2,],df$CS3,col="green")
axis(1,at=mp[2,],labels=df$V)
axis(4,at=seq(0,100,10))

创建这个

如果您查看图片,Y 轴会相互偏移。 如何使两个 Y 轴的 0 高度相同?

【问题讨论】:

  • 问“两个Y轴的0在同一高度”是什么意思?
  • 如果你有一个沉重的条形图:它会创建一个视觉强的 0 线。添加具有不同 y 比例且高度不同的折线图或点图会使视觉上难以阅读。在这种情况下,从技术上讲,应该绘制第二条 0 线,该线不在同一高度上
  • 我确实同情非英语母语人士/作家,但在这种情况下,我可能需要一个带注释的图像来传达预期的含义。自然语言似乎并没有“削减它”。

标签: r bar-chart


【解决方案1】:

这是使用dplyrggplot2 处理数据操作和可视化的另一种方法:

df <- df %>% 
      gather(D, d_val, D1:D3) %>% 
      gather(CS, cs_vsl, CS1:CS3)

这将提供数据集的长格式,即

head(df)

   V  D d_val  CS   cs_vsl
1 10 D1  2038 CS1 72.81172
2 20 D1   550 CS1 92.46159
3 30 D1   142 CS1 97.53483
4 40 D1    45 CS1 99.14255
5 50 D1    12 CS1 99.57128
6 60 D1     5 CS1 99.74991

使用长格式,可以这样绘制双轴图:

ggplot(df, aes(V)) + 
  geom_bar(aes(y=d_val, fill=D), stat="identity", position="dodge") + 
  geom_line(aes(y=cs_vsl*20, colour=CS)) +
  scale_y_continuous(sec.axis = sec_axis(~./20, name = "CS")) + ylab("D") +
  scale_x_continuous(breaks=seq(0,100, 10))

此方法将解决两个轴上的 0 不在同一条线上对齐的问题。

【讨论】:

    【解决方案2】:

    his comment 中声明的OP

    如果您有一个沉重的条形图:它会创建一个视觉上强烈的 0 线。添加具有不同 y 比例且高度不同的折线图或点图会使视觉上难以阅读。 从技术上讲,在这种情况下,应该绘制第二条不在同一高度上的 0 线

    (强调我的)

    这违反了OP的要求使两个Y轴的0在同一高度上

    刻面是另一种方法。它避免了同一图表中两个不同比例的 y 轴的视觉问题:

    library(ggplot2)
    ggplot(molten, aes(V, value, group = variable, colour = variable, fill = variable)) + 
      geom_col(data = molten[type == "D"], position="dodge") + 
      geom_line(data = molten[type == "CS"]) + 
      facet_wrap(~ type, scale = "free_y", ncol = 1L) + ylim(0, NA) +
      theme_bw()
    

    数据

    library(data.table)
    
    DT <- fread(
      "V   D1  D2  D3  CS1 CS2 CS3
    10  2038    1806    1643    72.81171847 64.52304394 58.69953555
    20  550 709 757 92.46159343 89.85351911 85.7449089
    30  142 192 271 97.53483387 96.71311183 95.42693819
    40  45  61  80  99.14255091 98.89246159 98.28510182
    50  12  20  30  99.57127546 99.6070025  99.35691318
    60  5   6   10  99.74991068 99.82136477 99.71418364
    70  2   2   3   99.82136477 99.89281886 99.82136477
    80  4   1   2   99.96427295 99.92854591 99.89281886
    90  1   0   1   100.0000000 99.92854591 99.92854591
    100 0   1   0   100.0000000 99.96427295 99.92854591"
    )
    
    molten <- melt(DT, id.vars = "V")
    molten[, type := stringr::str_extract(variable, "^\\D+")]
    molten[, id := stringr::str_extract(variable, "\\d+$")]
    

    【讨论】:

      【解决方案3】:

      我认为您需要在绘图功能中调整par,如下所示,par(yaxs="i") 在这种情况下可以帮助您:

      par(new=TRUE)
      par(yaxs="i")
      plot(mp[2,],df$CS1,xlim=c(0,40),type="l",col="red",axes=FALSE,ylim=c(0,100),ann=FALSE)
      lines(mp[2,],df$CS2,col="blue")
      lines(mp[2,],df$CS3,col="green")
      axis(1,at=mp[2,],labels=df$V)
      axis(4,at=seq(0,100,10))
      
      ?par from documentation:
      

      样式“i”(内部)只是找到一个带有漂亮标签的轴 在原始数据范围内。

      输出:

      我们可以看到,两个轴(y 轴主要和次要轴)都有零,距离基础的高度相同或处于相同的水平。

      【讨论】: