Why the bars point downwards and what to do about it
Bar plots in ggplot
are created such that bars for positive values point upwards starting at y = 0, while bars for negative values point downwards from the same axis. You are showing density on the y-axis which lies between 0 and 1 by definition. The logarithm of a number in that range is negative and therefore all your bars point downwards.
I don't know of a way to let ggplot
do what you want automatically. However, you can achieve your goal by plotting counts instead of density. This will work, because counts are 1 or larger, which means that the logarithm is positive. The exception is, of course, when counts are 0. The logarithm of 0 diverges and those values won't be plotted, which is equivalent to plotting bars with zero height.
A simple example
Since I don't have your data, I will show a solution using the built-in dataset faithful
. It should be easy enough to adapt that to your data.
As a demonstration of what I mean, I first show you an example, where the y-axis is not logarithmic. This has the advantage that the plot can be easily created without any tricks:
bw <- 2
n <- nrow(faithful)
ggplot(faithful, aes(waiting)) +
geom_histogram(aes(y = stat(density)), binwidth = bw)

Note that I have used stat(density)
instead of (..count..)/sum(..count..)
, which is a more modern way of achieving the same. I have also stored the binwdith and the number of data points into variables, since I will use those values often. The following code gives exactly the same image:
ggplot(faithful, aes(waiting)) +
geom_histogram(binwidth = bw) +
scale_y_continuous(
breaks = seq(0, 0.05, 0.01) * (bw * n),
labels = function(x) x / (bw * nrow(faithful))
)
Note that this time I plot counts, not density. However, I use the arguments breaks
and labels
in scale_y_continuous()
to redefine the positions of the breaks and their labels such that they show density nevertheless.
Solution with logarithmic y-axis
The same principle can be applied to the log-plot. First, I create the log-plot the same way you did, such that you can see that I end up with the same problem: the bars point downwards.
ggplot(faithful, aes(waiting)) +
geom_histogram(aes(y = stat(density)), binwidth = 2) +
scale_y_log10()

But by plotting counts and redefining the labels, you can get a more appropriate image:
ggplot(faithful, aes(waiting)) +
geom_histogram(binwidth = bw) +
scale_y_log10(
breaks = seq(0, 0.05, 0.01) * (bw * n),
labels = function(x) x / (bw * nrow(faithful))
)
