Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I draw a rectangular grid connecting the points

Tags:

r

ggplot2

I have a dataframe say named dfResultGrid with data as shown below.

dfResultGrid <- structure(list(x = c(3.5, 5.5, 7.5, 9.5, 5, 7, 9, 11, 6.5, 8.5, 
10.5, 12.5, 8, 10, 12, 14), y = c(3L, 4L, 5L, 6L, 5L, 6L, 7L, 
8L, 7L, 8L, 9L, 10L, 9L, 10L, 11L, 12L)), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "15", "16"))

Ok As per the discussion I am adding the code to get the above dataframe

BaseMatrix <- matrix(c(2, 1, 1.5, 2), nrow = 2)
dfGrid <- expand.grid(x=1:4, y=1:4)
pointMat <- t(as.matrix(dfGrid))
ResultMat <- BaseMatrix %*% pointMat
dfResultGrid <- as.data.frame(t(ResultMat))

A scatter plot of the 16 points are well distributed

ggplot(dfResultGrid, aes(x= x, y= y)) +
  geom_point()

How can I draw a grid like surface connecting those points ( parallel lines connecting the points). Geom_tile did not help in this case.

Expected plot is as given below. enter image description here Thanks so much.

like image 992
manoj1123 Avatar asked Nov 05 '25 02:11

manoj1123


2 Answers

Also using geom_segment, but here a more programmatic way. I have used the information that you were creating the grid based on a previous grid expansion and then matrix multiplication.

The code could certainly be shortened, especially the head/tail bits, but I left it like this for clarity.

library(ggplot2)

# you have used "expand grid" on a pattern of nxn
n <- 4
# your coordinate creation, slightly modified (using "n")
BaseMatrix <- matrix(c(2, 1, 1.5, 2), nrow = 2)
pointMat <- t(expand.grid(x = 1:n, y = 1:n))
ResultMat <- BaseMatrix %*% pointMat
dfResultGrid <- as.data.frame(t(ResultMat))
names(dfResultGrid) <- c("x", "y")

# Get coordinates for bottom and left points as segment start
pt_base <- head(dfResultGrid, n)
pt_left <- dfResultGrid[c(TRUE, rep(FALSE, n-1)), ]
# Get coordinates for top and right points as segment end
pt_top <- tail(dfResultGrid, n)
names(pt_top) <- c("xend", "yend")
pt_right <- dfResultGrid[c(rep(FALSE, n-1), TRUE), ]
names(pt_right) <- c("xend", "yend")
# cbind xend/yend to x/y, and rbind vertical to horizontal segment coordinates
df_seg <- rbind(cbind(pt_base, pt_top), cbind(pt_right, pt_left))

ggplot(dfResultGrid, aes(x, y)) +
  geom_point() +
  geom_segment(data = df_seg, aes(x, y, xend = xend, yend = yend))

Created on 2021-01-20 by the reprex package (v0.3.0)

like image 69
tjebo Avatar answered Nov 06 '25 16:11

tjebo


You can use geom_segment() to connect two points only. The following code can produce your desired segments.

ggplot(dfResultGrid, aes(x= x, y= y)) + geom_point() + 
  geom_segment(aes(x = x[1], y = y[1], xend = x[13], yend =y[13])) + 
  geom_segment(aes(x = x[1], y = y[1], xend = x[4], yend =y[4]))   + 
  geom_segment(aes(x = x[2], y = y[2], xend = x[14], yend =y[14])) +
  geom_segment(aes(x = x[3], y = y[3], xend = x[15], yend =y[15])) + 
  geom_segment(aes(x = x[4], y = y[4], xend = x[16], yend =y[16])) + 
  geom_segment(aes(x = x[5], y = y[5], xend = x[8], yend =y[8]))  + 
  geom_segment(aes(x = x[9], y = y[9], xend = x[12], yend =y[12])) +
  geom_segment(aes(x = x[13], y = y[13], xend = x[16], yend =y[16])) 

enter image description here

I don't know a smarter way to do this, but I found that in base R we can get the almost the same result with more efficient code.

k = 1: nrow(mygrid)-1
plot(dfResultGrid, pch = 19); 

with(dfResultGrid, segments(x[k], y[k], x[k+4], y[k+4]) + 
     segments(x[4], y[4], x[16], y[16]) +  
     segments(x[1], y[1], x[13], y[13])  )

enter image description here

like image 28
Abdur Rohman Avatar answered Nov 06 '25 15:11

Abdur Rohman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!