Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot2 plot an angle between two lines

Tags:

r

ggplot2

I would like to plot an angle between two lines using ggplot2, meaning something similar to the bold red line in the plot below. Is there an easy solution to this?

plot_with_red_line

Data and code to make the plot without the red line:

library(tidyverse)

df <- tibble(
  line = c("A", "A", "B", "B"),
  x = c(1, 5, 1, 3),
  y = c(1, 3, 1, 5))

ggplot(
  df, aes(x, y, group = line))+
  geom_path()
like image 904
Steen Harsted Avatar asked Nov 30 '25 16:11

Steen Harsted


2 Answers

have a look at geom_curve, e.g. :

ggplot(  df, aes(x, y, group = line))+
  geom_path() +
  geom_curve(aes(x = 1.5, y = 2, xend = 2, yend = 1.5), curvature = -0.5, color = "red", size = 3)

enter image description here

You will have to tweak it a bit to use it in a more robust, automatic way, for example:

red_curve <- df %>%
  group_by(line) %>%
  summarise( avg_x = mean(x),
             avg_y = mean(y))

ggplot(  df, aes(x, y, group = line))+
  geom_path() +
  geom_curve( data = red_curve, aes(x = avg_x[1], y = avg_y[1], xend = avg_x[2], yend = avg_y[2]), curvature = 0.5, color = "red", size = 3)

enter image description here

like image 169
Arcoutte Avatar answered Dec 02 '25 06:12

Arcoutte


Here is a solution with geom_arc of the ggforce package.

library(ggplot2)
library(ggforce)

angle <- function(p, c){
  M <- p - c
  Arg(complex(real = M[1], imaginary = M[2]))
}

O <- c(1,1)
P1 <- c(5,3)
P2 <- c(3,5)
a1 <- angle(P1, O)
a2 <- angle(P2, O)

df <- data.frame(
  line = c("A", "A", "B", "B"),
  x = c(1, 5, 1, 3),
  y = c(1, 3, 1, 5)
)

ggplot(df, aes(x, y, group = line)) +
  geom_path() + 
  geom_arc(aes(x0 = 1, y0 = 1, r = 1, start = a1, end = a2), 
           color="red", size = 2, inherit.aes = FALSE)

enter image description here

The arc does not look like a true arc circle. That's because the aspect ratio is not set to 1. To set the aspect ratio to 1:

ggplot(df, aes(x, y, group = line)) +
  geom_path() + 
  geom_arc(aes(x0 = 1, y0 = 1, r = 1, start = a1, end = a2), 
           color="red", size = 2, inherit.aes = FALSE) + 
  coord_fixed()

enter image description here

like image 24
Stéphane Laurent Avatar answered Dec 02 '25 04:12

Stéphane Laurent



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!