I'm trying to force the grid of a scatter plot to be composed of squares, with x and y values that have different ranges.
I tried to force a square shape of the whole plot (aspect.ratio=1), but this does not solve the problem of different ranges. Then I tried to change limits of values of my axes.
1)Here is what I tried first:
p + theme(aspect.ratio = 1) +
coord_fixed(ratio=1, xlim = c(-0.050,0.050),ylim = c(-0.03,0.03))
2) I changed the ratio by using the range of the values for each axis:
p + coord_fixed(ratio=0.06/0.10, xlim = c(-0.050,0.050), ylim = c(-0.03,0.03))
3)Then I changed the limits of y to match those of x:
p + theme(aspect.ratio = 1) +
coord_fixed(ratio=1, xlim = c(-0.050,0.050),ylim = c(-0.05,0.05))
1) The grid on the background is composed by rectangles.
2) I would expect this to change the position of the tick marks automatically in order to give me a grid composed of squares. Still triangles.
3) It obviously worked 'cause I matched the ranges of x and y. But there was a lot of empty space in the graph.
Is there something else I should try?
Thanks in advance.
If you want the plot to be square and you want the grid to be square you can do this by rescaling the y variable to be on the same scale as the x variable (or vice versa) for plotting, and then inverting the rescaling to generate the correct axis value labels for the rescaled axis.
Here's an example using the mtcars
data frame, and we'll use the rescale
function from the scales
package.
First let's create a plot of mpg
vs. hp
but with the hp
values rescaled to be on the same scale as mpg
:
library(tidyverse)
library(scales)
theme_set(theme_bw())
p = mtcars %>%
mutate(hp.scaled = rescale(hp, to=range(mpg))) %>%
ggplot(aes(mpg, hp.scaled)) +
geom_point() +
coord_fixed() +
labs(x="mpg", y="hp")
Now we can invert the rescaling to generate the correct value labels for hp
. We do that below by supplying the inverting function to the labels
argument of scale_y_continuous
:
p + scale_y_continuous(labels=function(x) rescale(x, to=range(mtcars$hp)))
But note that rescaling back to the original hp
scale results in non-pretty breaks. We can fix that by generating pretty breaks on the hp
scale, rescaling those to the mpg
scale to get the locations where we want the tick marks and then inverting that to get the label values. However, in that case we won't get a square grid if we want to keep the overall plot panel square:
p + scale_y_continuous(breaks = rescale(pretty_breaks(n=5)(mtcars$hp),
from=range(mtcars$hp),
to=range(mtcars$mpg)),
labels = function(x) rescale(x, from=range(mtcars$mpg), to=range(mtcars$hp)))