0
votes

I am trying to generate a set of plots with log-scaled axes and the same coordinates on both axes, as well as a square aspect ratio. Let's consider the following hypothetical data:

set.seed(1)
x <- rnorm(30, 50, 20)
y <- x + 20 + rnorm(30, 0, 10)

By using the code below, I obtain a rectangular plot:

p <- qplot(x, y) + 
  scale_x_continuous(trans = "log2") + 
  scale_y_continuous(trans = "log2") + 
  coord_equal()

rectangular plot

Now if I try to force the aspect ratio to 1:1 with the theme() function, it breaks the equal coordinate system:

p + theme(aspect.ratio = 1)

square plot

Is there a way to get both the equal scaling and the square aspect ratio that does not imply to manually change the limits for each graph? I would need to apply the same code to a whole series of data with different values and thus different limits.

1

1 Answers

1
votes

By default, ggplot2 will scale based on your data. But most of the scale_xxx functions provide a limits parameter that you can fine tune. Using your above example

p <- qplot(x, y) + 
  scale_x_continuous(trans = "log2", limits=c(8,128)) + 
  scale_y_continuous(trans = "log2", limits=c(8,128)) + 
  coord_equal()
p + theme( aspect.ratio=1 )

enter image description here

You also didn't need to provide the theme if you used coord_fixed() instead of coord_equal().

p <- qplot(x, y) + 
  scale_x_continuous(trans = "log2", limits=c(8,128)) + 
  scale_y_continuous(trans = "log2", limits=c(8,128)) + 
  coord_fixed( ratio=1 )
p

EDIT #1

Didn't see that one of you random x points was less than 8. Revised code

p <- qplot(x, y) + 
  scale_x_continuous(trans = "log2", limits=c(4,128)) + 
  scale_y_continuous(trans = "log2", limits=c(4,128)) + 
  coord_fixed( ratio=1)
p

enter image description here

EDIT #2 (Per additional rewording in the question)

If you want the range to be scaled dependent on your data, simply use the range() function in base R. So using the above variables...

xy.limits <- range( c(x,y) )

p <- qplot(x, y) + 
  scale_x_continuous(trans = "log2", limits=xy.limits) + 
  scale_y_continuous(trans = "log2", limits=xy.limits) + 
  coord_fixed( ratio=1)
p

Now if you want to limits to be clean multiples of 2, then you will have to do some data manipulation based on the computed values of xy.limits, which is a numeric vector of length 2.