r-lib / isoband

isoband: An R package to generate contour lines and polygons.
https://isoband.r-lib.org
Other
130 stars 14 forks source link

Corrects label angle for current aspect ratio #28

Closed eliocamp closed 3 years ago

eliocamp commented 3 years ago

This PR addresses #27 by correcting the label angle at draw time to compensate by the viewport aspect ratio.

Example code:

library(isoband)
library(grid)

x <- (0:(ncol(volcano) - 1))/(ncol(volcano) - 1)
y <- ((nrow(volcano) - 1):0)/(nrow(volcano) - 1)
lines <- isolines(x, y, volcano, 5*(19:38))

g <- isolines_grob(
  lines, breaks = 20*(5:10),
  label_placer = label_placer_middle(),
  gp = gpar(
    fontsize = 10,
    lwd = c(1, 2, 1, 1),
    col = c("grey50", "grey20", "grey50", "grey50")
  )
)

grid.newpage()
grid.draw(g)

With current master branch. Notice the lower-right "100", for example:

Exaggerated version:

WIth this PR:

Exaggerated version:

clauswilke commented 3 years ago

I'm fine with this in principle, but is there any way the computation could break, e.g. when you divide by 0 or when the tan() function returns Inf?

eliocamp commented 3 years ago

Good question.

I don't think there's any risk of dividing by zero, since Sx is a dimension, which if grid is sensible enough, should only be zero if the drawing area is zero pixels wide. At that point, the angle of your labels is the least of your problems.

I tested it anyway. atan(1/0), atan(Inf) and atan(tan(pi/2)) all return a sensible pi/2, so it seems that atan is safe for any input value.

The only problem I could envision is if both Sy and Sx are zero (that is, drawing area has zero extent). Then, atan(0/0) is NULL. Would you like me to add a check for that?

clauswilke commented 3 years ago

Let's just make sure that the angle is always a reasonable number. So why not add the following code:

theta <- atan(tan(...))
labels_data$theta <- ifelse(is.finite(theta), theta, 0)
eliocamp commented 3 years ago

Sounds fair. Latest commit adds that line.

clauswilke commented 3 years ago

Thanks!