Reputation: 55
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()
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)
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.
Upvotes: 1
Views: 2139
Reputation: 311
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 )
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
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.
Upvotes: 2