I need to plot randonmly a set of points is a 5X5 grid.
basically I need to plot a set of 2 points (can be horizontaly or verticaly), and a set of other 3 points, is a 5x5 grid.
the position of the points should be randomly attributed.
at the end it should look like something like this (i can do in a "static" code, but i cannot do it as a random atributtion)
par(xaxs = "i", yaxs = "i")
plot.new()
plot.window(xlim = c(0.5, 5.5), ylim = c(0.5, 5.5))
grid(nx = 5, ny = 5, col = "black", lty = "dashed")
box(lwd = 1)
# PLot points
points(1, 5, pch = 16, col = "blue", cex = 1.5)
points(2, 5, pch = 16, col = "blue", cex = 1.5)
points(1, 1, pch = 16, col = "pink", cex = 1.5)
points(1, 2, pch = 16, col = "pink", cex = 1.5)
points(1, 3, pch = 16, col = "pink", cex = 1.5)
This function will perform the algorithm. It does so by enumerating all possible valid pairs of blue dots (there are only 40) and valid triples of pink dots (there are only 30). It then samples a valid set of blue dots, then repeatedly samples random sets of pink dots until there are no clashes. It then uses your plotting code to draw the result:
random_points <- function() {
blue_pos <- cbind(c(1:20, c(1:25)[-c(5, 10, 15, 20, 25)]),
c(6:25, c(1:25)[-c(1, 6, 11, 16, 21)]))
pink_pos <- cbind(c(1:15, 1:3, 6:8, 11:13, 16:18, 21:23),
c(6:20, 2:4, 7:9, 12:14, 17:19, 22:24),
c(11:25, 3:5, 8:10, 13:15, 18:20, 23:25))
blue <- pink <- blue_pos[sample(nrow(blue_pos), 1),]
while(any(pink %in% blue)) pink <- pink_pos[sample(nrow(pink_pos), 1),]
par(xaxs = "i", yaxs = "i")
plot.new()
plot.window(xlim = c(0.5, 5.5), ylim = c(0.5, 5.5))
grid(nx = 5, ny = 5, col = "black", lty = "dashed")
box(lwd = 1)
for(i in 1:2) points(1 + (blue[i] - 1) %% 5,
1 + (blue[i] - 1) %/% 5,
pch = 16, col = "blue", cex = 1.5)
for(i in 1:3) points(1 + (pink[i] - 1) %% 5,
1 + (pink[i] - 1) %/% 5,
pch = 16, col = "pink", cex = 1.5)
}
Testing it out randomly 9 times gives us:
par(mfrow = c(3, 3))
for(i in 1:9) random_points()
Related
I am trying to make the following graph with R-plot:
I have the following code in R:
x = 0:8
f = log2(x)
plot(x, f, main="Função Logarítmica", xlab="X - Abscissas", ylab="Y - Ordenadas", t='l', ylim=c(-3,3), xlim=c(0,8), col=4, axes=F)
axis(1, pos=0, at=seq(from=0, to=8, by=0.2))
axis(2, pos=0)
# Inclui linhas de grade
abline(h=seq(-3,3,0.5),v=seq(-3,8,0.5),lty=3,col="gray", lwd=2)
The graph generated with the R-plot:
How should I make my R graph look like the figure?
I'm not sure what it is you want to change in the figure, but here's a reasonable replica:
x = seq(0.1, 8, 0.1)
f = log2(x)
plot(x, f, main = "Função Exponencial",
xlab = "X - Abscissas", ylab = "Y - Ordenadas", t = 'n',
ylim= c(-3, 3), xlim = c(0, 8), col = 4, axes = FALSE)
polygon(x = c(0, 8, 8, 0), y = c(-3, -3, 3, 3), col= "#e3e9ff")
abline(h = seq(-3, 3, 0.1), v = seq(-3, 8, 0.1), col = "white", lwd = 2)
lines(x, f, lwd = 2, col = "red3")
axis(1, pos = 0, at = 0:8)
axis(2, pos = 0)
text(label = c("\u215b", "\u00bc", "\u00bd"),
c(0.125, 0.25, 0.5), c(0.2, -0.2, -0.2), cex = 1.3)
for(i in seq(-3, 3)) {
lines(c(0, 2^i, 2^i), c(i, i, 0), lty = 2)
points(2^i, i, pch = 16, cex = 1.5)
}
This code gets the data needed to make two different lines. I was wondering if there was a way to see if two lines intersected easily.
# generate data
red <- matrix(runif(n = 4, min = 0, max = 1), nrow = 2)# gets the 4 points for the first line
blue <- matrix(runif(n = 4, min = 0, max = 1), nrow = 2)# gets the 4 points for second line
# make a plot
plot(red, col = "red", pch = 16, cex = 2,
asp = 1, xlim = c(0,1), ylim = c(0,1),
xlab = "", ylab = "")##plots both points red
abline(v = c(0,1), col = "grey", lty = 2)
abline(h = c(0,1), col = "grey", lty = 2)
segments(red[1,1], red[1,2], red[2,1], red[2,2], lwd = 2, col = "red")#Makes the line segment
points(blue, col = "blue", pch = 16, cex = 2,
asp = 1, xlim = c(0,1), ylim = c(0,1))# does same thing for blue line
segments(blue[1,1], blue[1,2], blue[2,1], blue[2,2], lwd = 2, col = "blue")
##makes all of the plots and can see if the plot intersects.`
Here's a practical answer using simple algebra wrapped up in a function.
The process is to find the slope and y intercept of both lines, and solve simultaneous equations to find the intersection. If both line segments have the same gradient the answer is undefined so return NA.
Return the x, y co-ordinates of the intersection if it is within the x range of one of the line segments, otherwise return NA
check_intersect <- function(mat1, mat2)
{
dy1 <- mat1[,2][which.max(mat1[,1])] - mat1[,2][which.min(mat1[,1])]
dy2 <- mat2[,2][which.max(mat2[,1])] - mat2[,2][which.min(mat2[,1])]
dx1 <- max(mat1[,1]) - min(mat1[,1])
dx2 <- max(mat2[,1]) - min(mat2[,1])
m1 <- dy1/dx1
m2 <- dy2/dx2
if(m1 == m2) return(NA)
c1 <- mat1[1, 2] - m1 * mat1[1, 1]
c2 <- mat2[1, 2] - m2 * mat2[1, 1]
x <- (c2 - c1)/(m1 - m2)
y <- m1 * x + c1
if(x > min(mat1[,1]) & x < max(mat1[,1]))
return(c(x, y))
else
return(NA)
}
Now test this with a reprex:
set.seed(123)
red <- matrix(runif(n = 4, min = 0, max = 1), nrow = 2)# gets the 4 points for the first line
blue <- matrix(runif(n = 4, min = 0, max = 1), nrow = 2)# gets the 4 points for second line
# make a plot
plot(red, col = "red", pch = 16, cex = 2,
asp = 1, xlim = c(0,1), ylim = c(0,1),
xlab = "", ylab = "")##plots both points red
abline(v = c(0,1), col = "grey", lty = 2)
abline(h = c(0,1), col = "grey", lty = 2)
segments(red[1,1], red[1,2], red[2,1], red[2,2], lwd = 2, col = "red")#Makes the line segment
points(blue, col = "blue", pch = 16, cex = 2,
asp = 1, xlim = c(0,1), ylim = c(0,1))# does same thing for blue line
segments(blue[1,1], blue[1,2], blue[2,1], blue[2,2], lwd = 2, col = "blue")
p <- check_intersect(red, blue)
points(p[1], p[2], cex = 2)
p
#> [1] 0.5719010 0.6781469
Created on 2020-03-24 by the reprex package (v0.3.0)
plot(1, pch = 19, cex = 3, col = "red")
points(1, pch = 1, cex = 3, col = "black", lwd = 2)
legend("top",
"sym",
pch = 19,
col = "red",
cex = 2,
pt.cex = 4)
legend("top",
"sym",
pch = 1,
col = "black",
cex = 2,
pt.cex = 4)
In R, a black borderline can be added to a solid red circle like:
Then, how can I use the symbol with added types for the legend?
As the code shows, legends cannot be added but overlapped.
Thanks.
Using bty = "n"
plot(1, pch = 19, cex = 3, col = "red")
points(1, pch = 1, cex = 3, col = "black", lwd = 2)
legend("top",
"sym",
bty = "n",
pch = 19,
col = c("red"),
cex = 2,
pt.cex = 4)
legend("top",
"sym",
bty = "n",
pch = 1,
col = c("black"),
cex = 2,
pt.cex = 4)
Created on 2019-02-14 by the reprex package (v0.2.1)
Anoter option is to use pch symbol that works with background option, it can be used only when pch = 21:25.
plot(1, pch = 19, cex = 3, col = "red")
points(1, pch = 1, cex = 3, col = "black", lwd = 2)
legend("top",
"sym",
pch = 21,
pt.bg="red",
cex = 2,
pt.cex = 4)
How does the fillOddEven parameter work in the polygon function in R? I have tried a couple of examples but can't spot a change:
layout(matrix(1:2,ncol=2))
x <- c(1:9, 8:1)
y <- c(1, 2*(5:3), 2, -1, 17, 9, 8, 2:9)
plot(1:10)
polygon(x, y, col = "orange", lty = 2, lwd = 2, border = "red",fillOddEven = T)
plot(1:10)
polygon(x, y, col = "orange", lty = 2, lwd = 2, border = "red",fillOddEven = F)
I have one plot and i need to adjust legends in a row. How can i do it?
plot(x,y)
legend(c("x","y"))
I need legend should be in one line
----- x --------- y
Regards
You want to set horiz=TRUE in legend. Here's a comparison of the default behavior (horiz=FALSE) to horiz=TRUE.
This plot is based on the second example from the legend documentation:
layout(matrix(1:2,nrow=1))
# `horiz=FALSE` (default behavior)
plot(x, sin(x), type = "l", ylim = c(-1.2, 1.8), col = 3, lty = 2, main="horiz=FALSE (Default)")
points(x, cos(x), pch = 3, col = 4)
lines(x, tan(x), type = "b", lty = 1, pch = 4, col = 6)
legend(-1, 1.9, c("sin", "cos", "tan"), col = c(3, 4, 6),
text.col = "green4", lty = c(2, -1, 1), pch = c(NA, 3, 4),
merge = TRUE, bg = "gray90")
# `horiz=TRUE`
plot(x, sin(x), type = "l", ylim = c(-1.2, 1.8), col = 3, lty = 2, main="horiz=TRUE")
points(x, cos(x), pch = 3, col = 4)
lines(x, tan(x), type = "b", lty = 1, pch = 4, col = 6)
legend(-1, 1.9, c("sin", "cos", "tan"), col = c(3, 4, 6),
text.col = "green4", lty = c(2, -1, 1), pch = c(NA, 3, 4),
merge = TRUE, bg = "gray90", horiz=TRUE)