Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to annotate a reference line at the same angle as the reference line itself?

Tags:

r

I need to find a way to annotate a reference line at the same angle as the reference line itself.

The following statement will produce the reference line and the label above it. However, the slope of the line may change and I need to find a way make sure the annotation is always at the same angle.

plot(1:10,1:10) 
abline(a=8, b=-1)
text(x=4, y=5, "reference line label", srt=-28)

enter image description here

Is there a simple way to do it in R? Thanks in advance

like image 516
Max C Avatar asked Aug 01 '12 20:08

Max C


3 Answers

One way is by setting the plot aspect ratio, using the asp argument, and then to calculate the angles using the specified asp:

asp <- 2

plot(1:10,1:10, asp=asp) 
abline(a=8, b=-1)
text(x=4, y=5, "reference line label", srt=180/pi*atan(-1*asp))

abline(a=4, b=-2)
text(x=1, y=3, "reference line label", srt=180/pi*atan(-2*asp))

enter image description here

Setting a different asp:

asp <- 0.8

plot(1:10,1:10, asp=asp) 
abline(a=8, b=-1)
text(x=4, y=5, "reference line label", srt=180/pi*atan(-1*asp))

abline(a=4, b=-2)
text(x=1, y=3, "reference line label", srt=180/pi*atan(-2*asp))

enter image description here

like image 167
Andrie Avatar answered Oct 08 '22 19:10

Andrie


An addendum to @Andrie's answer: instead of hard-coding the aspect ratio in the plot the first time to get the relative coordinate scales, you can recover the current working aspect ratio with the following function:

getCurrentAspect <- function() {
   uy <- diff(grconvertY(1:2,"user","inches"))
   ux <- diff(grconvertX(1:2,"user","inches"))
   uy/ux
}

So you can create your plot: set asp <- getCurrentAspect(); and proceed with the rest of @Andrie's solution.

For all I know this function exists somewhere in the R ecosystem, but I haven't seen it ...

like image 43
Ben Bolker Avatar answered Oct 08 '22 17:10

Ben Bolker


A similar solution with ggplot2

data <- data.frame(x = 1:10, y = 1:10)
intercept <- 10
slope <- -1
ggplot(data, aes(x,y)) + geom_point(shape=1) +  
  geom_abline(intercept = intercept, slope = slope) + 
  geom_text(x=4, y=5, label="my label", angle=atan(slope)*180/pi)

with slope 1

intercept <- 10
slope <- -2
ggplot(data, aes(x,y)) + geom_point(shape=1) +  
  geom_abline(intercept = intercept, slope = slope) + 
  geom_text(x=4, y=5, label="my label", angle=atan(slope)*180/pi)

with slope 2

like image 27
Maiasaura Avatar answered Oct 08 '22 19:10

Maiasaura