'R: Erasing Lines on ggplot2 - drawing half rectangles
I am working with the R programming language.
I generated some random data and plotted the following graph:
library(ggplot2)
var_1 = rnorm(1000,20,20)
var_2 = rnorm(1000,20,20)
my_data = data.frame(var_1, var_2)
ggplot(data=my_data, aes(x=var_1, y=var_2)) + geom_point()
I now want to make the following pattern on this graph:
I tried to do this with the following code, but this is the closest I could get:
a1 = ggplot(data=my_data, aes(x=var_1, y=var_2)) +
geom_point()+
geom_hline(yintercept=0, color = "red") +
geom_vline(xintercept=0, color = "red")
a2 = a1 + geom_point() +
geom_hline(yintercept=50, color = "red") +
geom_vline(xintercept=50, color = "red")
My Question: Could someone please show me a "direct" way to make this pattern on this graph? Is there some way to "erase" these extra lines?
Suppose I had a data frame ("my_points") that looked like this:
my_points = data.frame(var_1_point_1 = 0, var_1_point_2 = 50, var_2_point_1 = 0, var_2_point_2 = 50)
Could the graph be made using "my_data", and the lines be made by "referencing" the points in "my_points"? For example, something like this:
a1 = ggplot(data=my_data, aes(x=var_1, y=var_2)) +
geom_point()+
geom_hline(yintercept my_points[1,2], color = "red") +
geom_vline(xintercept=my_points[1,1], color = "red")
Thanks!
Solution 1:[1]
You'll need to use geom_segment instead of geom_hline or geom_vline since you'll need to specify xend and yend for each segment.
library(tidyverse)
var_1 = rnorm(1000,20,20)
var_2 = rnorm(1000,20,20)
my_data = data.frame(var_1, var_2)
ggplot(data=my_data, aes(x=var_1, y=var_2)) +
geom_point() +
geom_segment(aes(x = -50, xend = 0, y = 0, yend = 0), color = "red") +
geom_segment(aes(x = 0, xend = 0, y = 0, yend = -50), color = "red") +
geom_segment(aes(x = -50, xend = 50, y = 50, yend = 50), color = "red") +
geom_segment(aes(x = 50, xend = 50, y = 50, yend = -50), color = "red")

Created on 2022-03-21 by the reprex package (v2.0.1)
Update
Since OP wish to use an extra dataframe, here is the updated code:
library(ggplot2)
var_1 = rnorm(1000,20,20)
var_2 = rnorm(1000,20,20)
my_data = data.frame(var_1, var_2)
mypoint <- data.frame(var_1_point_1 = c(-50, 0),
var_1_point_2 = c(0, -50),
var_2_point_1 = c(-50, 50),
var_2_point_2 = c(50, -50))
ggplot(data=my_data, aes(x=var_1, y=var_2)) +
geom_point() +
geom_step(data = mypoint, aes(var_1_point_1, var_1_point_2), color = "red") +
geom_step(data = mypoint, aes(var_2_point_1, var_2_point_2), color = "red")

Created on 2022-03-22 by the reprex package (v2.0.1)
Solution 2:[2]
People tend to forget about geom_linerange - in vanilla ggplot sadly only available for vertical lines. But there is also ggstance::geom_linerangeh. Those would allow you to pass a data frame with your x/y coordinates and you will "only" need two geom layers for vertical and for horizontal lines (if your lines always start at the edge of the plot). You could apply the same idea with geom_segment of course, then without need of another package.
library(ggplot2)
library(ggstance)
## changed data frame my points:
x <- y <- c(0, 50)
my_points <- data.frame(x, y)
ggplot() +
geom_point(aes(x = var_1, y = var_2), data = my_data) +
geom_linerange(aes(x = x, ymin = -Inf, ymax = y), data = my_points, color = "red", size = 2) +
geom_linerangeh(aes(xmin = -Inf, xmax = x, y = y), data = my_points, color = "red", size = 2)

Solution 3:[3]
Another option would be to make your own stat and use this with geom_segment:
library(ggplot2)
var_1 <- rnorm(1000, 20, 20)
var_2 <- rnorm(1000, 20, 20)
my_data <- data.frame(var_1, var_2)
## changed data frame my points:
x <- y <- c(0, 50)
my_points <- data.frame(x, y)
StatEdge <- ggproto("StatEdge", Stat, compute_group = function(data, scales) {
x <- c(rep(-Inf, nrow(data)), data$x)
y <- c(data$y, rep(-Inf, nrow(data)))
xend <- rep(data$x, nrow(data))
yend <- rep(data$y, nrow(data))
data.frame(x, xend, y, yend)
})
## now you can use the new stat for your geom
ggplot() +
geom_point(aes(x = var_1, y = var_2), data = my_data) +
geom_segment(data = my_points, aes(x, y), stat = "edge", size = 2, color = "red")

Created on 2022-03-21 by the reprex package (v2.0.1)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | tjebo |
| Solution 3 | tjebo |



