【问题标题】:How to improve the aspect of ggplot histograms with log scales and discrete values如何使用对数刻度和离散值改进 ggplot 直方图的方面
【发布时间】:2014-07-09 06:19:15
【问题描述】:

我正在尝试提高我需要用对数刻度表示的离散值直方图的清晰度和方面。

请考虑以下 MWE

set.seed(99)
data <- data.frame(dist = as.integer(rlnorm(1000, sdlog = 2)))
class(data$dist)
ggplot(data, aes(x=dist)) + geom_histogram()

产生

然后

ggplot(data, aes(x=dist)) + geom_line() + scale_x_log10(breaks=c(1,2,3,4,5,10,100))

这可能更糟

因为现在它给人的印象是“1”和“2”之间缺少某些东西,并且也不完全清楚哪个条的值“1”(条在右边刻度线)以及哪个柱的值为“2”(柱在刻度的左侧)。

我知道从技术上讲,ggplot 为对数刻度提供了“正确”的视觉答案。然而,作为观察者,我在理解它时遇到了一些问题。

有什么可以改进的吗?

编辑:

当我将 Jaap 解决方案应用于我的真实数据时会发生这种情况

x=0 和 x=1 之间以及 x=1 和 x=2 之间的下降从何而来?我的值是离散的,但是为什么绘图也映射 x=1.5 和 x=2.5?

【问题讨论】:

  • 这可能是微不足道的,但尝试减少垃圾箱的数量??
  • @koundy 在我看来这并没有什么帮助。请参阅我的答案中的示例。

标签: r ggplot2


【解决方案1】:

首先想到的是玩binwidth。但这也不是一个很好的解决方案:

ggplot(data, aes(x=dist)) +
  geom_histogram(binwidth=10) +
  scale_x_continuous(expand=c(0,0)) +
  scale_y_continuous(expand=c(0.015,0)) +
  theme_bw()

给出:


在这种情况下,最好使用密度图。但是,当您使用 scale_x_log10 时,您将收到一条警告消息 (Removed 524 rows containing non-finite values (stat_density))。这可以通过使用 log plus one 转换来解决。

以下代码:

library(ggplot2)
library(scales)

ggplot(data, aes(x=dist)) +
  stat_density(aes(y=..count..), color="black", fill="blue", alpha=0.3) +
  scale_x_continuous(breaks=c(0,1,2,3,4,5,10,30,100,300,1000), trans="log1p", expand=c(0,0)) +
  scale_y_continuous(breaks=c(0,125,250,375,500,625,750), expand=c(0,0)) +
  theme_bw()

会给出这个结果:

【讨论】:

  • 出于某种奇怪的原因,在我的真实数据上使用您的解决方案时,我在 x=0 和 x=1 以及 x=1 和 x=2 之间出现了下降,为什么?在 0 和 1 之间映射没有任何价值,因为在 MWE 中我的值是离散的。 (已添加图片)
  • 由于您提供的样本数据也是离散的,这可能不是问题。查看您的绘图,它可能与您的 y 轴的定义有关。刻度线在 y 轴底部确实杂乱无章,这很奇怪。您能否分享您使用的数据(或足够大的数据样本)的确切代码和dput?否则,很难说出这种行为的确切原因是什么。
  • log1p,很好,不知道!
【解决方案2】:

我想知道,如果缩放 y 轴而不是 x 轴会怎样。只要值为 0,它就会导致很少的警告,但可能会达到您的目的。

set.seed(99)
data <- data.frame(dist = as.integer(rlnorm(1000, sdlog = 2)))
class(data$dist)
ggplot(data, aes(x=dist)) + geom_histogram() + scale_y_log10()

此外,您可能希望将频率显示为数据标签,因为人们可能会忽略 y 比例,并且需要一些时间才能意识到 y 比例是对数的。

ggplot(data, aes(x=dist)) + geom_histogram(fill = 'skyblue', color = 'grey30') + scale_y_log10() +
  stat_bin(geom="text", size=3.5, aes(label=..count.., y=0.8*(..count..)))

【讨论】:

    【解决方案3】:

    解决方案可能是将您的数据转换为因子:

    library(ggplot2)
    set.seed(99)
    data <- data.frame(dist = as.integer(rlnorm(1000, sdlog = 2)))
    ggplot(data, aes(x=factor(dist))) + 
        geom_histogram(stat = "count") + 
        theme(axis.text.x = element_text(angle = 90, hjust = 1))
    

    导致:

    【讨论】:

    • 您不需要预先这样做,您也可以将其转换为ggplot函数内的因子变量:ggplot(data, aes(x=factor(dist))) + geom_histogram()
    【解决方案4】:

    我遇到了同样的问题,并且受到@Jaap 回答的启发,我使用对数刻度的 x 轴摆弄了直方图 binwidth。

    如果您使用 binwidth = 0.201,条形将按预期并列。但是,这意味着两个 x 坐标之间最多只能有五个条。

    set.seed(99)
    data <- data.frame(dist = as.integer(rlnorm(1000, sdlog = 2)))
    class(data$dist)
    ggplot(data, aes(x=dist)) + 
       geom_histogram(binwidth = 0.201, color = 'red') + 
       scale_x_log10()
    

    结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      • 1970-01-01
      • 2019-02-25
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多