1

I want to plot bar plots using ggplot. I used scale_y_log10 to rescale the y axis. When use the script below, I get bars that are in both directions (upward and downward) and the bars start from 1. I understand that it is because, log10(1)=0.

ggplot (data=dat, aes(x=Col2,y=Col4,fill=Col3,group=Col1))+
geom_bar(stat="identity")+ facet_grid(.~Col1,scales="free_x",space="fixed")+
ylab("")+xlab("")+scale_fill_discrete("")+
scale_y_log10("#Counts",breaks=c(.1,1,10,100,1000),expand=c(0,0))+
theme_bw()+
theme(axis.text.x=element_text(angle=45,hjust=1,vjust=1))

Now, I want to force the bars to start from a lower value (say 0.1 or 0.01) and make all the bars in upward direction. How can I do that? Tried to find related posts and info but had no luck. Can someone direct me if there are such info already?

Edit: I want to use scale_y_log10 because most of the bars are low and some are extremely high. If I use scale_y_continuous, the shorter bars are not visible properly.

Abhishek
  • 279
  • 2
  • 5
  • 18
  • You get bars in different direction because some y values becomes negative - for example - log10(0.1) is -1. – Didzis Elferts Mar 10 '14 at 08:41
  • just a quick thought - have you considered transforming your data, for example adding a constant so that your minimum value would be 1 and taking log of them would start the bars from 0? – Sarunas Mar 10 '14 at 08:42
  • Didzis I understand the fact. Sarunas Thats a good idea but the label will still remain the same. May be I wait some time if there are other solutions. If I dont get any, I might do so. Anyway thanks! – Abhishek Mar 10 '14 at 08:52

1 Answers1

6

You can define your own scale, instead of using scale_y_continuous(trans="log10")). In the example below, you will have to change the argument from=-2 to you specific example.

# defining example data (since I don't have your data)
data(mtcars)
mtcars <- rbind(mtcars, mtcars)
mtcars <- rbind(mtcars, mtcars)
mtcars <- rbind(mtcars, mtcars)
mtcars <- rbind(mtcars, mtcars)
mtcars[1, "cyl"] <- 2
# sample plot
c <- ggplot(mtcars, aes(factor(cyl))) + geom_bar()
c + scale_y_log10() # this starts from 1
# defining the scale change
require(scales)
mylog_trans <- function(base=exp(1), from=0) 
{
  trans <- function(x) log(x, base)-from
  inv <- function(x) base^(x+from)
  trans_new("mylog", trans, inv, log_breaks(base=base), 
            domain = c(base^from, Inf))
}
# 
c + scale_y_continuous(trans = mylog_trans(base=10, from=-2)) # starts from 1e-2 
c + scale_y_continuous(trans = mylog_trans(base=10, from=-5)) # starts from 1e-5

As you can see in the above example, this plot can be very misleading. The two plots display the same data, but look very different, so be careful when using this scale-change.

shadow
  • 21,823
  • 4
  • 63
  • 77
  • Thank you shadow. It seems it does what I was looking for. But the bars are misleading. Probably plotting the values would be a better idea in that case. I will play around with it. – Abhishek Mar 10 '14 at 14:25