rggplot2scalecoordinate-transformation

Using ggplot2, how to position a geom_tile according to untransformed coordinates ratios while using the coord_trans function?


The initial plot is:

rect <- data.frame(x = 100, y = 50)
line <- data.frame(x = c(1, 200), y = c(100, 1))

library(ggplot2)
plot1 <- ggplot(mapping = aes(x, y)) +
  scale_x_continuous(limits=c(1, 200), expand=c(0,0), breaks = c(1,50,100,150,200)) +
  scale_y_continuous(limits=c(1, 100), expand=c(0,0), breaks = c(1,25,50,75,100)) +
  theme(axis.title=element_text(colour="black",size=22)) +
  theme(axis.text=element_text(colour="black",size=20)) +
  theme(plot.margin=unit(c(0.3, 0.8, 0.1, 0.2),"cm")) +
  geom_tile(data = rect, aes(width = 100, height = 50), alpha = 0.4) + 
  geom_line(data = line) + 
  theme(panel.grid.major=element_line(colour="grey60"))
plot1

enter image description here

The goal is to modulus_trans(0.3) the axes scales in such a way that the black line follows these transformations, but not the grey box which must remain positioned according to the ratio of untransformed coordinates (i.e., starting from 25% of x and y, and then covering 50% of the width and height).

The coord_trans function transforms the scales and the line appropriately, but also the box, unfortunately:

library(scales)
plot2 <- ggplot(mapping = aes(x, y)) + 
  scale_x_continuous(limits=c(1, 200), expand=c(0,0), breaks = c(1,50,100,150,200)) +
  scale_y_continuous(limits=c(1, 100), expand=c(0,0), breaks = c(1,25,50,75,100)) +
  theme(axis.title=element_text(colour="black",size=22)) +
  theme(axis.text=element_text(colour="black",size=20)) +
  theme(plot.margin=unit(c(0.3, 0.8, 0.1, 0.2),"cm")) +
  geom_tile(data = rect, aes(width = 100, height = 50), alpha = 0.4) + 
  geom_line(data = line) + 
  theme(panel.grid.major=element_line(colour="grey60")) +
  coord_trans(x = modulus_trans(0.3), y = modulus_trans(0.3))
plot2  

enter image description here

Is there a simple way to produce the following desired plot by positioning the box according to % of x and y, but not manually?

enter image description here

Thanks for help


Solution

  • I think I would just create a little function to calculate where points with the given proportions of the transformed co-ordinates would be:

    f <- function(x, max = 200, min = 1, trans = modulus_trans(0.3)) {
      min_trans <- trans$trans(min)
      max_trans <- trans$trans(max)
      trans$inv(min_trans + x * (max_trans - min_trans))
    }
    

    This allows us to use geom_rect instead of geom_tile:

    plot2 <- ggplot(line, mapping = aes(x, y)) + 
      geom_line() + 
      geom_rect(aes(xmin = f(0.25, 200), xmax = f(0.75, 200),
                    ymin = f(0.25, 100), ymax = f(0.75, 100)), alpha = 0.4) +
      scale_x_continuous(limits = c(1, 200), breaks = c(1, 1:4 * 50)) +
      scale_y_continuous(limits = c(1, 100), breaks = c(1, 1:4 * 25)) +
      coord_trans(x = modulus_trans(0.3), y = modulus_trans(0.3), expand = FALSE) +
      theme(axis.title       = element_text(colour = "black", size = 22),
            axis.text        = element_text(colour = "black", size = 20),
            plot.margin      = unit(c(0.3, 0.8, 0.1, 0.2), "cm"), 
            panel.grid.major = element_line(colour = "grey60")) 
    

    And we can compare the results using patchwork

    library(patchwork)
    
    plot1/plot2
    

    enter image description here