r-lib / isoband

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

Drawing an `isolines_grob()` fails when the label covers the entire line #21

Closed paleolimbot closed 3 years ago

paleolimbot commented 3 years ago

I ran across this using the (awesome!) isolines_grob() to draw contours in a custom ggplot2 geom, where there are frequently tiny contours on the corners of the plot where pretty much any label function will place a label that results in zero values left in the resulting line. Reprexed:

library(isoband)
library(grid)

m <- matrix(c(0, 0, 0, 0, 0, 0,
              0, 0, 0, 1, 1, 0,
              0, 0, 1, 1, 1, 0,
              0, 1, 1, 0, 0, 0,
              0, 0, 0, 1, 0, 0,
              0, 0, 0, 0, 0, 0), 6, 6, byrow = TRUE)

df_lines <- isolines((1:ncol(m))/(ncol(m)+1), (nrow(m):1)/(nrow(m)+1), m, 0.5)
grob_lines <- isolines_grob(
  df_lines,
  gpar(fontsize = 1000),
  label_placer = label_placer_manual("0.5", 0.5, 0.5, 0)
)

grid.newpage()
grid.draw(grob_lines)
#> Error in unit(x, default.units): 'x' and 'units' must have length > 0

Created on 2021-05-03 by the reprex package (v2.0.0)

clauswilke commented 3 years ago

Thanks. If you have the free capacity, could you try to dig into what actually causes the error? I haven't looked at this code in a long time and don't immediately know what may be going on.

paleolimbot commented 3 years ago

Sure!

I think that clip_lines() is returning a line with zero values and it's erroring when the values get passed to polylineGrob():

https://github.com/wilkelab/isoband/blob/e5f7413b4f0b9f46124ff3eb1afac3ed5be8e434/R/isolines-grob.R#L197-L205

I should have a few moments later today to PR a fix in as well :)

clauswilke commented 3 years ago

Yes, this makes sense. Some lines will get clipped away entirely.

clauswilke commented 3 years ago

By the way, I'll be glad if isolines_grob() finds more use. I put a lot of effort into writing it but there isn't really any user-friendly interface to it at this time, so nobody uses it.

Future work could focus on more intelligent label placement. I implemented the minimally viable version and then I ran out of steam and pivoted to other things.

paleolimbot commented 3 years ago

It should definitely find more use! Knowing it existed at all saved me a few days at work.

I did have to shim a few things ( https://github.com/paleolimbot/ggoce/blob/master/R/geom-isopycnal.R#L322-L357 ) but the contours I'm drawing are really predictable and the current code was perfect. The main thing I was up against was that the default contours got plotted outside the plot bounds.