我正在努力提高离散值直方图的清晰度和方面,我需要用对数刻度表示。
请考虑以下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?
答案 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()
给出:
在这种情况下,最好使用密度图。但是,当您使用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()
会给出这个结果:
答案 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))
导致:
答案 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()
您还可能希望将频率显示为数据标签,因为人们可能会忽略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 :(得分: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()