Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Segment annotation on log10 scale works differently for the end and the beginning of the segment?

I found a rather confusing feature in ggplot while trying to annotate segments on log10 scale. Following code produces the plot below:

library(ggplot2)
dat <- data.frame(x = x <- 1:1000, y = log(x)) 
ggplot(dat, aes(x = x, y = y)) +
geom_line(size = 2) + scale_x_log10() +
annotate("segment", x = 0, xend = log10(100), y = log(100), yend = log(100), linetype = 2) +
annotate("segment", x = log10(100), xend = log10(100), y = 0, yend = log(100), linetype = 2)

enter image description here

Whereas this is what I am after:

ggplot(dat, aes(x = x, y = y)) +
geom_line(size = 2) + scale_x_log10() +
annotate("segment", x = 0, xend = log10(100), y = log(100), yend = log(100), linetype = 2) +
annotate("segment", x = 100, xend = log10(100), y = 0, yend = log(100), linetype = 2)

enter image description here

In other words, I have to log10 transform the endpoint of the segment on x-axis, but not the beginning. Does this behaviour have a logical explanation? I understand that aes() does the transformations...but in this case, transformations on x-axis should be uniform (well, log10), right?

I am working on:

R version 3.0.0 (2013-04-03)
Platform: x86_64-w64-mingw32/x64 (64-bit)
ggplot2_0.9.3.1 
like image 978
Mikko Avatar asked Apr 25 '13 09:04

Mikko


1 Answers

Found that this is a bug of scales() (not only for the scale_x_log10()) when it is used with annotate() and xend value is provided (it is already filled as issue by W.Chang). In this case transformation of xend is done only in one direction - log10 of value is not taked but power is calculated.

scale_x_log10() works without problems if, for example, "rect" is used in annotate() and xmin, xmax values are provided.

ggplot(dat,aes(x,y))+geom_line()+
  scale_x_log10()+
  annotate("rect",xmin=100,xmax=1000,ymin=log(10),ymax=log(200))

enter image description here

Workaround for this problem would be to use geom_segment() with data=NULL and all other values put inside the aes().

ggplot(dat, aes(x = x, y = y)) +
  geom_line(size = 2) + scale_x_log10() +
  geom_segment(data=NULL,aes(x = 100, xend = 100, y = 0, yend = log(100)), 
                                                             linetype = 2)

enter image description here

like image 50
Didzis Elferts Avatar answered Nov 15 '22 01:11

Didzis Elferts