r - grid_plot + tikzDevice + shared legend with latex mark up -


i've been trying follow this vignette on how make shared legend multiple ggplot2. given examples work is, in case, i'm using tikzdevice export tikzpicture environment. main problem seems widths of legend keys not correctly captured grid_plot.

i came minimal r code reproduces problem:

require(ggplot2) require(grid) require(gridextra) require(cowplot) require(tikzdevice)  tikz(file = "./tmp.tex", width = 5.6, height = 2.2, standalone = t ) mpg2 <- mpg  mpg2$cyl = as.factor(mpg2$cyl) levels(mpg2$cyl) <- c("\\textbf{\\textsc{four}}",                       "\\textbf{\\textsc{five}}",                       "\\textbf{\\textsc{six}}",                       "\\textbf{\\textsc{seven}}",                       "\\textbf{\\textsc{eight}}")  plot.mpg <- ggplot(mpg2, aes(x=cty, colour=cyl, y = hwy)) +       geom_point() +      theme(legend.position='none')  legend <- get_legend(plot.mpg + theme(legend.position = "top"))  print(plot_grid(legend,                   plot.mpg, nrow=2, ncol=1,align='h',                   rel_heights = c(.1, 1)))  dev.off() 

the generated pdf file (after compiling tmp.tex) looks this:

enter image description here

as can observe, first legend key (four) partially displayed , legend key (eight) invisible. tried changing tikz command width no avail.

also, suspect reason behind problem grid_plot command incorrectly measures length of legend keys if contain latex mark up. show cause of problem, consider changing levels of mpg2$cyl following:

levels(mpg2$cyl) <- c("four",                       "five",                       "six",                       "seven",                       "eight") 

this should result in following plot perfect legend:

enter image description here

please note example above meant reproduce problem , not i'm trying do. instead, have 4 plots i'm trying use shared common legend them.

anyone please can tell me how fix legend problem when contains latex mark up?

by way, here sessioninfo():

r version 3.3.2 (2016-10-31) platform: x86_64-apple-darwin13.4.0 (64-bit) running under: os x yosemite 10.10.5  locale: [1] en_us.utf-8/en_us.utf-8/en_us.utf-8/c/en_us.utf-8/en_us.utf-8  attached base packages: [1] grid      stats     graphics  grdevices utils     datasets  methods   [8] base       other attached packages: [1] tikzdevice_0.10-1 dplyr_0.5.0       gdata_2.17.0      cowplot_0.7.0     [5] gridextra_2.2.1   ggplot2_2.2.0      loaded via namespace (and not attached):  [1] gtools_3.5.0       colorspace_1.2-6   dbi_0.5            rcolorbrewer_1.1-2  [5] plyr_1.8.4         munsell_0.4.3      gtable_0.2.0       labeling_0.3        [9] rcpp_0.12.6        scales_0.4.1       filehash_2.3       digest_0.6.10      [13] tools_3.3.2        magrittr_1.5       lazyeval_0.2.0     tibble_1.1         [17] assertthat_0.1     r6_2.1.3          

thank all.

ggplot2 appears calculate string widths based on raw string opposed box sizes should returned tex. i'm guessing it's calculation done (ie not @ drawing time) in guides code. workaround edit relevant widths manually in gtable, calling getlatexstrwidth explicitly. note added package in preamble otherwise default font doesn't show bold small caps.

require(ggplot2) require(grid) require(gridextra) require(tikzdevice)  settikzdefaults(overwrite = true) preamble <- options("tikzlatexpackages")  options("tikzlatexpackages" = c(preamble$tikzlatexpackages, "\\usepackage{bold-extra}"))  tikz(file = "./tmp.tex", width = 5.6, height = 2.2, standalone = true ) mpg2 <- mpg  mpg2$cyl = as.factor(mpg2$cyl)  levels(mpg2$cyl) <- c("\\textbf{\\textsc{four}}",                       "\\textbf{\\textsc{five}}",                       "\\textbf{\\textsc{six}}",                       "\\textbf{\\textsc{seven}}",                       "\\textbf{\\textsc{eight}}")  p <- ggplot(mpg2, aes(x=cty, colour=cyl, y = hwy)) +    geom_point() +   theme(legend.position='none')    leg <- cowplot::get_legend(p + theme(legend.position = "top"))  ids <- grep("label",leg$grobs[[1]]$layout$name) pos <- leg$grobs[[1]]$layout$l[ids] wl <- sapply(leg$grobs[[1]][["grobs"]][ids], function(g) getlatexstrwidth(g[["label"]]))  leg$grobs[[1]][["widths"]][pos] <- unit(wl, "pt")  grid.arrange(p, top=leg)  dev.off() 

enter image description here


Comments

Popular posts from this blog

How to understand 2 main() functions after using uftrace to profile the C++ program? -

c# - Update a combobox from a presenter (MVP) -

How to put a lock and transaction on table using spring 4 or above using jdbcTemplate and annotations like @Transactional? -