ggplot分组条形图上使用对数刻度出现问题

5

我正在尝试使用R中的ggplot2制作具有对数刻度的分组条形图。我的目标是在R中重新创建以下图表。

enter image description here

因为产生它的程序无法生成高分辨率图形,所以我需要对数刻度,因为数字范围从1到1000以上,而且各种数字都有。

这是数据框的简化版本的代码片段,以及我一直在使用的代码。我已经能够使用ggplot2制作图表,但我的问题是数据中有很多1最终被绘制为0,而0则显示为-1。以下是我的R绘图结果。

genus_counts <- read.table(text = "Genus variable value
1  Lepisosteus  JBGC462     0
2      Lepomis  JBGC462     6
3  Micropterus  JBGC462     2
4        Perca  JBGC462     2
5    Ictalurus  JBGC462     1
6  Lepisosteus   JBGC13    13
7      Lepomis   JBGC13     0
8  Micropterus   JBGC13     0
9        Perca   JBGC13     0
10   Ictalurus   JBGC13     0", header = TRUE)


ggplot(genus_counts, aes(x=Genus, y=value, fill=variable))+
      geom_bar(stat="identity", position="dodge")+
      scale_y_log10()

enter image description here

从数学上讲,我理解为什么会出现这种情况(并且条形图上的对数刻度并不是很理想)。但是否有另一种方法可以调整绘图(或我输入到绘图中的数字),以更接近我试图模拟的绘图?


也许是 scale_y_sqrt() - Mako212
1
有很多类似的问题,例如这个。此外,最好的建议始终是不要混合使用条形图和对数轴。带有0或-的情况是不可能的。即使所有值都是正数,条形图也会误导,因为(1)我们线性地感知沿着条形的距离;(2)条形的相对大小取决于选择底部值的任意性。因此,可以随意抑制或夸大差异。仅仅因为你可以找到其他人捏造的例子,并不意味着这样做就可以接受。 - dww
可选方案包括:(1)如果所有值都为正,则使用点图表;(2)使用自由(线性)y轴刻度分面显示各组别;或者(3)像您的示例数据一样,如果跨度不是很大,则只需使用线性坐标轴。 - dww
2个回答

4
如果您使用scale_y_sqrt(),则会显示以下内容,这似乎非常适合您的示例图。我添加了一个值为1000的行,以说明您可以同时看到像1和2这样的小值以及大值。

enter image description here


但请记住,这个解决方案也违反了比例墨水原则,就像使用对数刻度的图表一样。 - Claus Wilke

4
您遇到的问题根本原因在于具有正计数或0计数的条形图是无限长的。当您更改y轴的轴范围时,请看看会发生什么:
genus_counts <- read.table(text = "Genus variable value
1  Lepisosteus  JBGC462     0
2      Lepomis  JBGC462     6
3  Micropterus  JBGC462     2
4        Perca  JBGC462     2
5    Ictalurus  JBGC462     1
6  Lepisosteus   JBGC13    13
7      Lepomis   JBGC13     0
8  Micropterus   JBGC13     0
9        Perca   JBGC13     0
10   Ictalurus   JBGC13     0", header = TRUE)


ggplot(genus_counts, aes(x=Genus, y=value, fill=variable))+
  geom_bar(stat="identity", position="dodge")+
  scale_y_log10(limits = c(0.1, 15))

enter image description here

在这种情况下,条形图向负方向延伸得相当远。但是请等一下,我们可以走得更远:
ggplot(genus_counts, aes(x=Genus, y=value, fill=variable))+
  geom_bar(stat="identity", position="dodge")+
  scale_y_log10(limits = c(1e-100, 15))

enter image description here

在对数刻度上制作条形图只有当参考点为1时才有意义,这样你才可以看到相对于1的值的变化,小于1的数字会显示为向下的条形。ggplot2正确地处理了这个问题。如果你尝试将参考点设置为0,则所有条形都将无限长,而你永远无法选择适当的坐标轴范围。
请注意,您展示的示例图表是错误的,因为它在y轴上的1的位置放置了一个0。0的值在该图中不可见,所有条形的长度都是误导性的。
最后,有人提到了平方根刻度。它避免了无限长的条形的问题。
ggplot(genus_counts, aes(x=Genus, y=value, fill=variable))+
  geom_bar(stat="identity", position="dodge")+
  scale_y_sqrt(limits = c(0, 15), breaks = (0:4)^2)

enter image description here

我也不太喜欢这个解决方案,因为条形长度很容易让人感到困惑。请注意,与值6相对应的条形长度只有与值1相对应的条形长度的2.5倍左右。我们的大脑会误解这样的条形图,并关注条形的相对长度,而不是y轴上的数字。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接