根据相同的数据框添加第二个y轴

时间:2018-04-27 12:21:07

标签: r ggplot2

我正在尝试使用ggplot2创建一个箱线图,并且需要从同一数据框中创建两个代表两个不同比例的轴。基本上我正在绘制三个附属物的每两个不同物种的表面积与体积比,并且其中一个附属物与另外两个相比具有非常高的SA:V比率,这使得难以将它们全部放在同一图表上。

我已经为箱线图重新创建了我的数据和代码,以展示我在说什么。如果可能的话,我希望背鳍显示在同一图表上,但是在不同的y轴刻度上(也将在图表上显示),这样箱图的方框都是可见的。

SAV <- c(seq(.35, .7, .01), seq(.09, .125, .001), seq(.09, .125, .001))
Type <- c(rep("Pectoral Fin", 36), rep("Dorsal fin", 36), rep("Fluke", 36))
Species <- c(rep(c(rep("Sp1", 18), rep("Sp2", 18)), 3))
appendage <- data.frame(SAV, Type, Species)

ggplot(aes(y = appendage$SAV, 
           x = factor(appendage$Type, levels = c("Dorsal fin", "Fluke")),
           fill = appendage$Species), 
       data = appendage) + 
 geom_boxplot(outlier.shape = NA) + 
 labs(y = expression("SA:V("*cm^-1*")"), x="") + 
 scale_x_discrete(labels = c("PF", "DF", "F")) + 
 scale_fill_manual(values = c("black", "gray"))

如果任何人可以帮助我,这将是伟大的!

enter image description here

2 个答案:

答案 0 :(得分:0)

一种可能性是使用facet_wrap

appendage %>% 
  mutate(
    Type = factor(Type, 
                  levels = c("Dorsal fin", "Fluke", "Pectoral Fin"), 
                  labels = c("DF", "PF", "F"))) %>% 
  ggplot(aes(Type, SAV, fill = Species)) + 
  geom_boxplot(outlier.shape=NA) + 
  labs(y=expression("SA:V("*cm^-1*")"),x="") + 
  scale_fill_manual(values=c("black","gray")) + 
  facet_wrap(~Type, scales="free") + 
  theme(axis.ticks.x = element_blank(), 
        strip.background = element_blank(),
        strip.text.x = element_blank())

ScriptApp class

答案 1 :(得分:0)

首先,就像其他人评论的那样,我推荐这种类型的情节。双轴倾向于使比较更难,&amp;即使他们意识到这一点,也会在视觉上混淆观众。

也就是说,可以使用ggplot2和&amp;一旦我们解决了原始代码中的其他几个问题,我将在下面展示一种方法:

问题1 :您正在将数据框传递给ggplot()。在这种情况下,$中没有美元符号aes()

而不是:

ggplot(aes(y = appendage$SAV, 
           x = factor(appendage$Type), # ignore the levels for now; see next issue
           fill = appendage$Species), 
       data = appendage) + 
...

使用:

ggplot(aes(y = SAV, 
           x = factor(Type),
           fill = Species), 
       data = appendage) + 
...

第2期:哪个附属物具有非常高的SA:V?

从用于生成样本数据集的代码中,它应该是“Pectoral Fin”,但最终结果显示为“DF”。我假设完整术语和&amp;之间的映射。轴标签为:

  • “胸鳍” - &gt; “PF”
  • “背鳍” - &gt; “DF”
  • “Fin” - &gt; “F”

...所以这看起来像是将Type作为因子传递给aes()中的x参数,并在scale_x_discrete()中设置轴标签之间的滑动。

由于您使用factor(),因此在那里设置标签也更为简洁。将它保存在同一个地方会使这些事情更容易被发现。

而不是:

ggplot(aes(y = SAV, 
           x = factor(Type, levels = c("Dorsal fin", "Fluke")),
           fill = Species), 
       data = appendage) + 
...

使用:

ggplot(aes(y = SAV,
           x = factor(Type, 
                      levels = c("Dorsal fin", "Fluke", "Pectoral Fin"),
                      labels = c("DF", "F", "PF")),
           fill = Species),
       data = appendage) +
...

我改变了各种因素的顺序,因为我觉得它对于与次要y轴(通常在右边)对应的x轴类别在视觉上更有意义,在其他x轴类别的右边。如果这不是所需的情况,您可以更改它。只需确保同时更改levels = ...labels = ...

辅助y轴解决方案

  1. 手动重新调整违规附肢的值(无论哪个鳍都是),直到其范围与其他附肢的范围有些相似。 (在下面的示例中,我使用了y / 5的简单除法,但也可以使用更复杂的函数。)

  2. 使用重新缩放功能的反转作为转换,为y轴指定sec.axis()选项。 (在这种情况下为y * 5。)

  3. 相应地标记原始y轴(左)和次y轴(右),以清楚说明每个轴的刻度适用于哪个附肢。

  4. 最终代码+结果:

    k = 5 #rescale factor
    
    ggplot(aes(y = ifelse(Type == "Pectoral Fin", 
                          SAV / k, SAV),
               x = factor(Type, 
                          levels = c("Dorsal fin", "Fluke", "Pectoral Fin"),
                          labels = c("DF", "F", "PF")),
               fill = Species),
           data = appendage) +
      geom_boxplot(outlier.shape = NA) + 
      scale_y_continuous(sec.axis = sec_axis(trans = ~. * k,
                                             name = expression("SA:V ("*cm^-1*") PF"))) +
      labs(y = expression("SA:V ("*cm^-1*") DF / F"), x = "") + 
      scale_fill_manual(values = c("black", "gray"))
    

    plot