Gmisc specify a monospaced font in a boxGrob

I am building a Markov diagram using Gmisc::boxGrob. The text in each of the boxes is essentially a minitable, and it is very hard to get the columns to align using the default variable spacing font. The boxGrob() help specifies that one can specify a font for the text in a gpar(fontfamily = 'fontname') parameter in the boxGrob() function. But I have been unable to get the code to accept specification of a monospaced font using the fontfamily variable. Does anyone have a way to set the fontfamily to a monospaced font?

Tp <- boxGrob(glue("State 1:  Tp",
                   "  ",
                   "Entered:    72 (IA: 48, IAK: 24)",
                   "Censored:   8 (IA:   7, IAK:   1)",
                   "Failed:       11 (IA:   4, IAK:   7)",
                   "To II:          53 (IA: 37, IAK: 16)",
                   .sep = "\n"), 
              txt_gp = gpar(fontsize = 11), 
              width = .4, height = .4, y = 0.8, x = 0.2)
II <- boxGrob(glue("State 2:  II",
                   "  ",
                   "Entered:      53 (IA: 37, IAK: 16)",
                   "Censored:   30 (IA: 20, IAK: 10)",
                   "Failed:           0 (IA:   0, IAK:   0)",
                   "To LostII:     23 (IA: 17, IAK:    6)",
                   .sep = "\n"), 
                txt_gp = gpar(fontsize = 11), width = .4, height = .4,
                y = 0.8, x = 0.8)
LostII <- boxGrob(glue("State 3:  LostII",
                   "  ",
                   "Entered:    23 (IA:  17, IAK:  6)",
                   "Censored:  18 (IA:  14, IAK:  4)",
                   "Failed:         5 (IA:   3, IAK:   2)",
                   "To Failed:     5 (IA:   3, IAK:   2)",
                    .sep = "\n"),  
                txt_gp = gpar(fontsize = 11), width = .4, height = .4,
                y = 0.2, x = 0.8)
Failed <- boxGrob(glue("State 4:  Failed",
                   "  ",
                   "Entered:        16 (IA: 7, IAK: 9)",
                   "Failed:           16 (IA: 7, IAK: 9)",
                    .sep = "\n"), 
                txt_gp = gpar(fontsize = 11), width = .4, height = .4,
                y = 0.2, x = 0.2)
Tp; II; LostII; Failed

connectGrob(Tp, II, type = 'horizontal')
connectGrob(II, LostII, type = 'vertical')
connectGrob(LostII, Failed, type = 'horizontal')
connectGrob(Tp, Failed, type = 'vertical')

Thanks in advance to anyone that can help me with this.
Larry Hunsicker

Addendum: I have found a solution -- actually two parts of a solutions -- but the situation is a bit messy.
First, dkaufman found a way to change the fontfamily within a Gmisc::boxGrob, at least in Windows.
https://github.com/gforge/Gmisc/issues/51
Basically this is a correct way to set the txt_gp gpar options, which include setting fontfamily, etc.

windowsFonts(
  A=windowsFont("TT Courier New"),
  B=windowsFont("TT Helvetica"),
  C=windowsFont("TT Montserrat")
)
boxGrob(txt, txt_gp = getOption("boxGrobTxt", default = gpar(fontfamily = "A")))

That permits you to specify a monospaced font, which permits one to enter multiline text for a box, knowing that the columns will line up.

The hang up is that, again at least in Windows, the chunk machinery natively has access to only a limited number of fonts, and I'm not sure that any of them is monospaced. But there is another fix for this issue. RStudio's own Winston Chang has created a package extrafont that enables Windows users to make the Windows fonts accessible to the chunks. This also requires a fix to add these fonts to the regular R system pdf compiler, for which there is a function in extrafont.
https://blog.revolutionanalytics.com/2012/09/how-to-use-your-favorite-fonts-in-r-charts.html
Unfortunately I need to use the cairo pdf device for other reasons, and I haven't been able to get the combination of fixes to work right yet.
Could one of you RStudio types find out whether extrafont works with the Cairo pdf device? Thanks!

I think that the showtext package may be the way to go. I've modified the example to use showtext with a very different-looking font, so that it's obvious that it's working.

library(grid)
library(Gmisc)
library(glue)
library(showtext)

font_add_google("Rock Salt", "rock")
showtext_auto()
grid.newpage()

TxtGp <- getOption("boxGrobTxt", default = gpar(fontfamily = "rock", fontsize = 16))

Tp <- boxGrob(glue("State 1:  Tp",
                   "  ",
                   "Entered:    72 (IA: 48, IAK: 24)",
                   "Censored:    8 (IA:  7, IAK:  1)",
                   "Failed:     11 (IA:  4, IAK:  7)",
                   "To II:      53 (IA: 37, IAK: 16)",
                   .sep = "\n"), 
              txt_gp = TxtGp, 
              width = .4, height = .4, y = 0.8, x = 0.2)
II <- boxGrob(glue("State 2:  II",
                   "  ",
                   "Entered:    53 (IA: 37, IAK: 16)",
                   "Censored:   30 (IA: 20, IAK: 10)",
                   "Failed:      0 (IA:  0, IAK:  0)",
                   "To LostII:  23 (IA: 17, IAK:  6)",
                   .sep = "\n"), 
              txt_gp = TxtGp, width = .4, height = .4,
              y = 0.8, x = 0.8)
LostII <- boxGrob(glue("State 3:  LostII",
                   "  ",
                   "Entered:    23 (IA:  17, IAK:  6)",
                   "Censored:   18 (IA:  14, IAK:  4)",
                   "Failed:      5 (IA:   3, IAK:  2)",
                   "To Failed:   5 (IA:   3, IAK:  2)",
                       .sep = "\n"),  
                  txt_gp = TxtGp, width = .4, height = .4,
                  y = 0.2, x = 0.8)
Failed <- boxGrob(glue("State 4:  Failed",
                   "  ",
                   "Entered:     16 (IA:  7, IAK:  9)",
                   "Failed:      16 (IA:  7, IAK:  9)",
                       .sep = "\n"), 
                  txt_gp = TxtGp, width = .4, height = .4,
                  y = 0.2, x = 0.2)
Tp; II; LostII; Failed

connectGrob(Tp, II, type = 'horizontal')
connectGrob(II, LostII, type = 'vertical')
connectGrob(LostII, Failed, type = 'horizontal')
connectGrob(Tp, Failed, type = 'vertical')

It uses Google fonts, so you may have to search for fonts that are similar to the ones on your computer.

About extrafont: the extrafont package is really only getting minimal maintenance these days. Showtext may be a better solution in this case.

1 Like

Thanks, Winston! Showtext works. A reasonable monospaced font already in c:\windows\fonts is Lucida Console Regular. To use a font already in the windows font folder, substitute:

font_add("lucida", "c:/windows/fonts/lucon.ttf")

for the line in Winston's example:

font_add_google("Rock Salt", "rock")

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.