如何使用对数标度和离散值改进ggplot直方图的方面

时间:2014-07-09 06:19:16

标签: r ggplot2

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

请考虑以下MWE

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

产生

enter image description here

然后

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

可能更糟糕

enter image description here

因为现在它给人的印象是“1”和“2”之间缺少某些东西,而且还不完全清楚哪个条的值为“1”(条形图位于右侧勾选)和哪个栏的值为“2”(栏位于勾选的左侧)。

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

是否有可能改善某些事情?

编辑:

当我将Jaap解决方案应用于我的真实数据

时会发生这种情况

enter image description here

x = 0和x = 1之间以及x = 1和x = 2之间的下降来自哪里?我的值是离散的,但是为什么该图也是映射x = 1.5和x = 2.5?

4 个答案:

答案 0 :(得分:10)

首先想到的是玩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()

给出: enter image description here


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

以下代码:

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()

会给出这个结果: enter image description here

答案 1 :(得分:1)

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

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

导致: enter image description here

答案 2 :(得分:0)

我想知道,是否缩放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()

Basic Graph

您还可能希望将频率显示为数据标签,因为人们可能会忽略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..)))

enter image description here

答案 3 :(得分:0)

我遇到了同样的问题,在@Jaar 的回答的启发下,我使用 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()

结果:https://i.imgur.com/ydMiHyZ.png