I have a code that takes in positional data as well as values at that positional data and then plots it with geom_tile. The matrix size of the plot is not constant from data it
I don't think the method you have of identifying the small squares works. Not quite sure why, but I thought it might be easier to go back to scratch on this. Here is a generalised solution. First I will set up some data - with the dimensions, number of squares and location of the sub-grid all picked at random...
large_x <- sample(2:5,1) #large grid no of x squares
large_y <- sample(2:5,1) #large grid no of y squares
small_x <- sample(2:5,1) #small grid no of x squares
small_y <- sample(2:5,1) #small grid no of y squares
large_w <- round(runif(1,0.5,1.5),2) #width of large squares
large_h <- round(runif(1,0.5,1.5),2) #height of large squares
df <- expand.grid(x=large_w*(1:large_x),y=large_h*(1:large_y)) #large grid
divsq <- sample(nrow(df),1) #random row of df to determine square to divide
sm_x <- df$x[divsq] #coordinates of divided square
sm_y <- df$y[divsq]
df <- rbind(df[-divsq,], #large grid without subdivided square
expand.grid(x=sm_x-large_w*((1+1/small_x)/2-(1:small_x)/small_x), #x coordinates of small grid
y=sm_y-large_h*((1+1/small_y)/2-(1:small_y)/small_y))) #y coordinates of small grid
df$val <- sample(0:100,nrow(df))
df <- df[sample(nrow(df)),] #shuffle df for good measure!
Now I am going to ignore all the random parameters and just work with df
, which only contains x
, y
and val
columns. The approach is to look at the intervals between x values for constant y (and vice versa) and use this to work out the small square characteristics. This information can then be used to mark whether each data point belongs to a small square, after which the rest is straightforward.
xdists <- tapply(df$x,df$y,function(z) diff(sort(z))) #list of differences between x values for constant y
ydists <- tapply(df$y,df$x,function(z) diff(sort(z))) #list of differences between y values for constant x
smallw <- min(unique(unlist(xdists))) #identify small width
smallh <- min(unique(unlist(ydists))) #identify small height
#the next lines check for rows that contain diffs equal to the small values, and return the appropriate values of x or y
smally <- as.numeric(names(xdists)[sapply(xdists,function(z) min(abs(z-smallw))<0.0000001)]) #values of y corresponding to small grid
smallx <- as.numeric(names(ydists)[sapply(ydists,function(z) min(abs(z-smallh))<0.0000001)]) #values of x corresponding to small grid
nx <- length(smallx) #x-size of small grid
ny <- length(smally) #y-size of small grid
#this checks which data points are in small squares (allowing some tolerance for rounding)
df$small <- mapply(function(x,y) (min(abs(x-smallx))<0.0000001 &
min(abs(y-smally))<0.0000001),df$x,df$y)
df$w <- ifelse(df$small,smallw,smallw*nx)
df$h <- ifelse(df$small,smallh,smallh*ny)
ggplot(data=df, aes(x=x, y=y, width=w, height=h)) +
geom_tile(fill = "white", color="black") +
geom_text(aes(label = val), colour="black") +
coord_fixed()