具有对数刻度和自定义中断的直方图

Posted

技术标签:

【中文标题】具有对数刻度和自定义中断的直方图【英文标题】:Histogram with Logarithmic Scale and custom breaks 【发布时间】:2010-11-17 17:35:00 【问题描述】:

我正在尝试在 R 中生成一个直方图,其中 y 为对数刻度。目前我这样做:

hist(mydata$V3, breaks=c(0,1,2,3,4,5,25))

这给了我一个直方图,但是 0 到 1 之间的密度非常大(大约一百万个值差异),以至于你几乎无法辨认出其他任何条形。

然后我尝试做:

mydata_hist <- hist(mydata$V3, breaks=c(0,1,2,3,4,5,25), plot=FALSE)
plot(rpd_hist$counts, log="xy", pch=20, col="blue")

它给了我想要的东西,但底部显示的值是 1-6 而不是 0、1、2、3、4、5、25。它还将数据显示为点而不是条形。 barplot 有效,但我没有得到任何底轴。

【问题讨论】:

相关老问题:Make y-axis logarithmic in histogram using R 【参考方案1】:

直方图是穷人的密度估计。请注意,在您使用默认参数调用hist() 时,您会得到频率 而不是概率——如果您需要概率,请在调用中添加,prob=TRUE

至于对数轴的问题,不希望x轴变换就不要使用'x':

plot(mydata_hist$count, log="y", type='h', lwd=10, lend=2)

为您提供 log-y 比例尺 - 外观仍然有些不同,但可能可以调整。

最后,您还可以通过hist(log(x), ...) 获取数据日志的直方图。

【讨论】:

太棒了!我怎样才能修改底部的轴呢?我不想显示 1、2、3、4、5、6,而是显示 0 抑制 plot() 中的轴并显式调用 axis() 给出“位置”和“什么”允许您这样做。 不幸的是,“type = 'h'” 似乎不再起作用了(哇这个答案来自近 12 年前!!) 这会让我感到惊讶。基本 R 绘图函数不应更改。事实上,这对我来说很好,因为它应该:set.seed(123); z &lt;- cumsum(runif(100)); plot(z, type='h')【参考方案2】:

另一种选择是使用包ggplot2

ggplot(mydata, aes(x = V3)) + geom_histogram() + scale_x_log10()

【讨论】:

这是一个非常好的答案,并且自动化了许多可以在以后随时调整的细节。谢谢!【参考方案3】:

您的问题并不完全清楚您想要记录的 x 轴还是记录的 y 轴。使用条形时,记录的 y 轴不是一个好主意,因为它们锚定在零处,记录时变为负无穷大。您可以使用频率多边形或密度图来解决此问题。

【讨论】:

【参考方案4】:

Dirk 的回答很棒。如果你想要hist 产生的外观,你也可以试试这个:

buckets <- c(0,1,2,3,4,5,25)
mydata_hist <- hist(mydata$V3, breaks=buckets, plot=FALSE)
bp <- barplot(mydata_hist$count, log="y", col="white", names.arg=buckets)
text(bp, mydata_hist$counts, labels=mydata_hist$counts, pos=1)

最后一行是可选的,它在每个栏的顶部添加值标签。这对于对数比例图很有用,但也可以省略。

我还传递了mainxlabylab 参数来提供绘图标题、x 轴标签和 y 轴标签。

【讨论】:

【参考方案5】:

我已经组合了一个函数,它在默认情况下的行为与 hist 相同,但接受 log 参数。它使用了其他海报中的一些技巧,但添加了一些自己的技巧。 hist(x)myhist(x) 看起来一模一样。

原来的问题可以这样解决:

myhist(mydata$V3, breaks=c(0,1,2,3,4,5,25), log="xy")

功能:

myhist <- function(x, ..., breaks="Sturges",
                   main = paste("Histogram of", xname),
                   xlab = xname,
                   ylab = "Frequency") 
  xname = paste(deparse(substitute(x), 500), collapse="\n")
  h = hist(x, breaks=breaks, plot=FALSE)
  plot(h$breaks, c(NA,h$counts), type='S', main=main,
       xlab=xlab, ylab=ylab, axes=FALSE, ...)
  axis(1)
  axis(2)
  lines(h$breaks, c(h$counts,NA), type='s')
  lines(h$breaks, c(NA,h$counts), type='h')
  lines(h$breaks, c(h$counts,NA), type='h')
  lines(h$breaks, rep(0,length(h$breaks)), type='S')
  invisible(h)

读者练习:不幸的是,并非所有适用于 hist 的东西都适用于 myhist 。不过,这应该可以通过更多的努力来解决。

【讨论】:

【参考方案6】:

在不绘制图形的情况下运行 hist() 函数,对计数进行对数转换,然后绘制图形。

hist.data = hist(my.data, plot=F)
hist.data$counts = log(hist.data$counts, 2)
plot(hist.data)

它应该看起来像常规直方图,但 y 轴将是 log2 频率。

【讨论】:

为了防止 -Inf 您必须使用以下命令:hist.data$counts[hist.data$counts&gt;0] &lt;- log(hist.data$counts[hist.data$counts&gt;0], 2)【参考方案7】:

这是一个漂亮的 ggplot2 解决方案:

library(ggplot2)
library(scales)  # makes pretty labels on the x-axis

breaks=c(0,1,2,3,4,5,25)

ggplot(mydata,aes(x = V3)) + 
  geom_histogram(breaks = log10(breaks)) + 
  scale_x_log10(
    breaks = breaks,
    labels = scales::trans_format("log10", scales::math_format(10^.x))
  )

请注意,要在 geom_histogram 中设置中断,必须将它们转换为与 scale_x_log10 一起使用

【讨论】:

以上是关于具有对数刻度和自定义中断的直方图的主要内容,如果未能解决你的问题,请参考以下文章

在张量板中对数缩放 Y 轴

R:大数据集的直方图

直方图的 x 轴上不需要的空间

线性回归图解释

如何在 Python 中向直方图添加特定的 x 刻度线? [复制]

opencv直方图加刻度