15

Hi I'm making histogram using R, but the number of Y axis is so large that I need to turn it into logarithmic.See below my script:

hplot<-read.table("libl")
hplot
pdf("first_end")
hist(hplot$V1, breaks=24, xlim=c(0,250000000), ylim=c(0,2000000),main="first end mapping", xlab="Coordinates")
dev.off()

So how should I change my script? thx

LookIntoEast
  • 8,048
  • 18
  • 64
  • 92
  • 3
    It doesn't make sense to have a logarithmic y-axis on a histogram - the bars extend down to 0, which on the log-scale is negative infinity. – hadley Oct 20 '11 at 01:32

4 Answers4

25

You can save the histogram data to tweak it before plotting:

set.seed(12345)
x = rnorm(1000)

hist.data = hist(x, plot=F)
hist.data$counts = log10(hist.data$counts)

dev.new(width=4, height=4)
hist(x)

dev.new(width=4, height=4)
plot(hist.data, ylab='log10(Frequency)')

enter image description here

enter image description here

John Colby
  • 22,169
  • 4
  • 57
  • 69
  • 9
    This is a little misleading because you have shifted the baseline from 0 to 10^0 = 1. – hadley Oct 20 '11 at 01:32
  • @hadley Yea I think it's strange too. There's a reason you can't just pass `log='y'` like a normal plot. – John Colby Oct 20 '11 at 01:47
  • Worked nicely, just dev.new(width=4, height=4) didn't work saying "In (function () : Only one RStudio graphics device is permitted" as I am using RStudio. – saganas Oct 07 '14 at 14:43
  • @saganas yeah you can skip those in rstudio, the UI let's you navigate between plots – jena Nov 15 '19 at 10:07
4

Another option would be to use plot(density(hplot$V1), log="y").

It's not a histogram, but it shows just about the same information, and it avoids the illogical part where a bin with zero counts is not well-defined in log-space.

Of course, this is only relevant when your data is continuous and not when it's really categorical or ordinal.

pipefish
  • 898
  • 1
  • 9
  • 13
3

A histogram with the y-axis on the log scale will be a rather odd histogram. Technically it will still fit the definition, but it could look rather misleading: the peaks will be flattened relative to the rest of the distribution.

Instead of using a log transformation, have you considered:

  • Dividing the counts by 1 million:

    h <- hist(hplot$V1, plot=FALSE)

    h$counts <- h$counts/1e6

    plot(h)

  • Plotting the histogram as a density estimate:

    hist(hplot$V1, freq=FALSE)

Hong Ooi
  • 56,353
  • 13
  • 134
  • 187
  • 1
    A histogram with the y-axis in log scale is a rather common thing, specially if you want to take care of the tails, rare events that take extreme values. A reply to a similar question you can find it here: http://stackoverflow.com/questions/1245273/histogram-with-logarithmic-scale – Antoni Oct 11 '16 at 10:37
2

You can log your y-values for the plot and add a custom log y-axis afterwards.

Here is an example for a table object of random normal distribution numbers:

# data
count = table(round(rnorm(10000)*2))
# plot
plot(log(count) ,type="h",  yaxt="n", xlab="position", ylab="log(count)")
# axis labels
yAxis = c(0,1,10,100,1000)
# draw axis labels
axis(2, at=log(yAxis),labels=yAxis, las=2)

log data with log axis labeling

Tobi G.
  • 1,530
  • 2
  • 13
  • 16