Transformation doesn't transorm line segments

2019-07-21 05:21发布

问题:

I am trying to annotate a plot using some line segments. The x-axis is best displayed by a log transformation. I am using ggplot2 which handles transformations, which also means I shouldn't have to transform to location of my line segments. But when I apply a transformation, the line segments disappear (well - they don't "fit" into the plot window any more, due to the transformation). Any suggestions on how to get them to "follow" the transformation?

Minimal example:

library(ggplot2)
## Base plot:
B <- ggplot(data = data.frame(X = 10^(1:10), Y = 1:10),
            aes(x = X, y = Y)) + geom_point()
## Generate segments: 
S1 <- geom_segment(x = 1000, xend = 1000,
                   y = 3, yend = 5)
S2 <- geom_segment(x = 20, xend = 2.5e9,
                   y = 8, yend = 7)
## Generate transformation:
T <- scale_x_continuous(trans = "log")

Compare the following:

B               # Basic plot
B + T           # Basic plot, transformed
B + S1 + S2     # Basic, untransformed, with segments
B + S1 + S2 + T # Should be transformed with segments: segments missing

I know I could just transform the locations of the segments, but I'd really rather find a more ggplot2-style solution!

Hack solution:

S3 <- geom_segment(x = log(1000), xend = log(1000),
                   y = 3, yend = 5)
S4 <- geom_segment(x = log(20), xend = log(2.5e9),
                   y = 8, yend = 7)
B + S1 + S2
B + S3 + S4 + T #Fine, but not elegant.

Thanks!

回答1:

Not sure if the plot I've shown is what you expect. But if it is, the explanation below is valid.

In ggplot2 transformations are performed on aesthetics. And the data is transformed first before plotting (or doing anything of the sort of fitting, ex: geom_smooth etc.. is done on transformed data).

So, if you want the log transformation to be reflected on your segment, you'll have to wrap around with aes as:

S1 <- geom_segment(aes(x=1000, xend=1000, y=3, yend=5))
S2 <- geom_segment(aes(x=20, xend=2.5e9, y=8, yend=7))

And by the way, your transformation should be log10, NOT log:

T <- scale_x_continuous(trans = "log10")

Now, if you plot B + S1 + S2 + T:

One step further: Compare your B+S1+S2+T and the one with S1 and S2 modified with mine using:

ggplot_build(B+S1+S2)$data # and 
ggplot_build(B+S1+S2+T)$data

to see that the aesthetics get transformed accordingly.



标签: r ggplot2