Closed jokergoo closed 4 years ago
Not sure what exactly is going on in your code. I'll have to ask you to try to figure out the specific problem in more detail. The moment you start pushing viewports inside viewports and then try to calculate the width or height of a grob, things can go wrong, in particular when you're rotating grobs and using different types of units along x and y. (For a possibly somewhat related problem, see here: https://github.com/r-lib/gtable/issues/83)
In my testing code, the width and height are calculated correctly.
library(grid)
library(gridtext)
f <- function(rot) {
gb = richtext_grob(
month.name, x = ((3:14)+.5)/18,
box_gp = gpar(col = "red"),
rot = rot
)
grid.newpage()
grid.draw(
rectGrob(height = grobHeight(gb), width = grobWidth(gb))
)
grid.draw(gb)
}
f(30)
f(45)
f(90)
f(-45)
Created on 2020-02-04 by the reprex package (v0.3.0)
The reason is I want to create a viewport with the same height as the richtext_grob. Let's say, when I implement the heatmap package, I want to create a viewport to put the column names in, thus, I need the height of this viewport to have the same height of the column names, also when they are rotated.
Since the texts have absolute width and height, does it matter to calculate the size inside or outside a certain viewport?
A strange thing is when I run your example code in a completely new R session, there is still empty space above and below the text, no matter I directly plot it in an interactive window or save into a PDF file.
f(45)
But, it seems it only happens on my laptop (Macbook). If I run the same code in other PC, it is fine:
Also, I think the height of the grob is calculated from yext
from gb$children
s. This value is different from machines with the same grob.
E.g. for following grob where text is rotated with 45 degrees:
gb = richtext_grob(
month.name, x = ((3:14)+.5)/18,
box_gp = gpar(col = "red"),
rot = 45
)
and I check yext
for the first children of gb
(I think it is for January
):
gb$children[[1]]$yext
On my laptop:
[1] 10.89174 41.19233 19.40884 49.70943
On another PC:
[1] -11.15314 19.14218 -19.14218 11.15314
On Rstudio server:
[1] -19.42964 10.91254 -10.91254 19.42964
I'm not sure why you get this wide range of different numbers for yext
, but in any case, only the difference between the largest and the smallest numbers matters, and the difference is approximately the same in your three examples, at least within the expected accuracy of font metrics reported by different graphics devices.
library(gridtext)
library(grid)
diff(range(c(10.89174, 41.19233, 19.40884, 49.70943)))
#> [1] 38.81769
diff(range(c(-11.15314, 19.14218, -19.14218, 11.15314)))
#> [1] 38.28436
diff(range(c(-19.42964, 10.91254, -10.91254, 19.42964)))
#> [1] 38.85928
png()
gb <- richtext_grob(
month.name, x = ((3:14)+.5)/18,
box_gp = gpar(col = "red"),
rot = 45
)
gb$children[[1]]$yext
#> [1] -19.09486 11.20573 -11.20573 19.09486
diff(range(gb$children[[1]]$yext))
#> [1] 38.18972
dev.off()
#> quartz_off_screen
#> 2
pdf()
gb <- richtext_grob(
month.name, x = ((3:14)+.5)/18,
box_gp = gpar(col = "red"),
rot = 45
)
gb$children[[1]]$yext
#> [1] -19.14218 11.15314 -11.15314 19.14218
diff(range(gb$children[[1]]$yext))
#> [1] 38.28437
dev.off()
#> quartz_off_screen
#> 2
Created on 2020-02-06 by the reprex package (v0.3.0)
A couple of additional comments:
In general, grob width and height are only properly defined when a grob is placed into its final viewport. This creates an identifiability problem when you want to create a viewport the size of a grob. I would recommend against this approach, even if it seems that it should be possible.
I'm not discounting the possibility that there is something wrong with my code, but I'll need a very clear and minimal reprex that shows what exactly the problem is. As far as I can tell, grob heights are calculated correctly when gridtext is used inside ggplot, on different platforms.
Please use the reprex package to create examples, to make sure we know exactly what the state of the graphics device is when specific calls are made, and in what order things are executed.
Thanks!
Thanks for your reply. Now I tried to set align_widths
argument to TRUE
and FALSE
separately and I convert the height to mm
unit for easy reading. In theory, the three numbers in the following code should be all the same, but still on my Macbook, setting align_widths
or not gives different height for the text.
On other machines, the three numbers are identical.
library(gridtext)
library(grid)
gb = richtext_grob(month.name, rot = 90, align_widths = FALSE)
convertHeight(grobHeight(gb), "mm")
#> [1] 27.29755859375mm
gb = richtext_grob(month.name, rot = 90, align_widths = TRUE)
convertHeight(grobHeight(gb), "mm")
#> [1] 20.7077799479167mm
# if only September
gb = richtext_grob(month.name[9], rot = 90, align_widths = FALSE)
convertHeight(grobHeight(gb), "mm")
#> [1] 20.7077799479167mm
Created on 2020-02-06 by the reprex package (v0.3.0)
This is what I see (on OS X). Could you run the reprex with si = TRUE
, so we can compare the session info?
library(gridtext)
library(grid)
gb = richtext_grob(month.name, rot = 90, align_widths = FALSE)
convertHeight(grobHeight(gb), "mm")
#> [1] 20.7077799479167mm
gb = richtext_grob(month.name, rot = 90, align_widths = TRUE)
convertHeight(grobHeight(gb), "mm")
#> [1] 20.7077799479167mm
# if only September
gb = richtext_grob(month.name[9], rot = 90, align_widths = FALSE)
convertHeight(grobHeight(gb), "mm")
#> [1] 20.7077799479167mm
Created on 2020-02-06 by the reprex package (v0.3.0)
Hi, I updated the version of gridtext to 0.1.0.9000 (the github version. The previous one installed on my laptop was 0.1.0, from CRAN). Now everything is fine (also the in the plots).
library(gridtext)
library(grid)
gb = richtext_grob(month.name, rot = 90, align_widths = FALSE)
convertHeight(grobHeight(gb), "mm")
#> [1] 20.7077799479167mm
gb = richtext_grob(month.name, rot = 90, align_widths = TRUE)
convertHeight(grobHeight(gb), "mm")
#> [1] 20.7077799479167mm
# if only September
gb = richtext_grob(month.name[9], rot = 90, align_widths = FALSE)
convertHeight(grobHeight(gb), "mm")
#> [1] 20.7077799479167mm
Created on 2020-02-07 by the reprex package (v0.3.0)
The f()
function defined before:
f <- function(rot) {
gb = richtext_grob(
month.name, x = ((3:14)+.5)/18,
box_gp = gpar(col = "red"),
rot = rot
)
grid.newpage()
grid.draw(
rectGrob(height = grobHeight(gb), width = grobWidth(gb))
)
grid.draw(gb)
}
f(45)
Now I re-installed the version 0.1.0 from CRAN, everything is also working. I don't know why, but it works.
Thank you for your help!
I'm glad things work now. 0.1.0 and 0.1.0.9000 are essentially the same. It would have been strange if one worked and the other didn't.
Hi, thanks for developing this package for better configuring text under grid system! I am developing a package called ComplexHeatmap and I want to support gridtext with it. I found when
rot
is set to e.g. 30 inrichtext_grob()
function, the height calculated bygrobHeight()
is not identical to the height (or the width if the rotation is 90 degrees) of the longest text.I attached an example here. In the following plot, the height of the rectangles should be the same as the height of
September
, regardless of the rotation of the text. As a comparison, I also attached plots if usingtextGrob()
function and you can see the height of rectangles is exactly the same asSeptember
.I haven't tested
grobWidth()
onrichtext_grob
object, but I guess it should be similar.Thanks!