R: background or inserted image and text in lattice - r

I'd like to insert a watermark onto a lattice image. In ggplot2, I simply used the the annotate or annotation_custom options to place a logo image and a text below the logo in a corner of the plot. Is there a similar possibility in lattice? Or as an alternative - is it possible to use an image as background of the plot?

This is what Deepayan Sarkar offered on Rhelp a couple of years ago to a similar question:
barchart(variety ~ yield | site, data = barley, groups = year, layout = c(3,1),
page = function(n) {
grid.text(label = "Privileged and Confidential \nDRAFT",
x = unit(0.01, "npc"),
y = unit(0.95, "npc"),
just = c("left", "center")) })
Obviously you would also need to use grid graphics functions to place the logo, (but you haven't offered one to work with. The first two lines of this next code was found at #baptiste's blog page cited today on SO.) The second two lines were adapted from Paul Murrell's article in last years "R Journal" found with Rseek.org:
library(png)
m <- readPNG(system.file("img", "Rlogo.png", package="png"), FALSE)
rimg <- as.raster(m)
grid.raster(rimg, x=.05, y=.9, just="top", width=.1)

Related

Fixing spacing issue with annotations in cowplot/patchwork

I'm trying to combine several figures drawn in PowerPoint into a panel, using patchwork, cowplot, magick. However, I always feel that the distance between the annotation and the actual figure is too big, and I'm struggling to find a way that minimises the distance.
Is there a way to fix this issue?
Here's is my code.
library(patchwork)
library(cowplot)
library(magick)
# You can test with any other image, so the code should be reproduceable
design <- "./design.png"
courses <- "./courses.png"
# here I draw the figure using draw_image
design <- ggdraw() + draw_image(design, x = 0,
y = 0)
courses <- ggdraw() + draw_image(courses)
design / courses + plot_annotation(tag_levels = 'A')
A solution that fixed the problem was to use ggsave and playing around with the width and height, as suggested in the comments. For me, this one worked.
plot <- design / courses + plot_annotation(tag_levels = 'A')
ggsave("myplot.tiff", device = "tiff", height = "0.5")

Automatic line break in ggtitle

Is there a way to force an automatic line break in the ggtitle command?
As part of a shiny application I use different plots with an input variable for the title.
Unfortunately, some of these variable values are too long to be displayed.
I came across one possibility by inserting \n (or a line break) manually in advance (Details here: Improve editing of multiline title in ggplot that uses \n and extends far to the right). There, something like ggtitle(paste("", title, "", sep = "\n")) would be suggested.
Since including \n would be error prone as well as not flexible for different plot sizes I´m looking for another possibility.
Here is an minimal working example (adapted from lawyeR question linked above):
DF <- data.frame(x = rnorm(400))
title_example <- "This is a very long title describing the plot in its details. The title should be fitted to a graph, which is itself not restricted by its size."
plot <- ggplot(DF, aes(x = x)) + geom_histogram() +
ggtitle(title_example)
You can find a image here: https://i.stack.imgur.com/6MMKF.jpg
Do you have an idea how to e.g. adapt the sep = operator to break lines automatically or are there maybe packages/ workarounds? Thanks!
The ggtext package's text elements could help solve this. element_textbox_simple() automatically wraps the text inside. Try resizing the graphics device window, it adapts!
library(ggplot2)
library(ggtext)
DF <- data.frame(x = rnorm(400))
title_example <- "This is a very long title describing the plot in its details. The title should be fitted to a graph, which is itself not restricted by its size."
ggplot(DF, aes(x = x)) + geom_histogram() +
ggtitle(title_example) +
theme(plot.title = element_textbox_simple())
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Plots are squished when exporting to .pptx using officer

I'm using the officer package to write ggplots to Powerpoint, and even though my plots look good in my Rstudio viewer, my plots are getting "squished" when I add them to any custom slide with smaller content boxes.
I did my best to reproduce my issue with the following code:
library(tidyverse)
library(officer)
p <- data.frame(x = rnorm(100)) %>%
ggplot() +
geom_density(aes(x)) +
labs(title = "This is a title") +
annotate("text", x = 0, y = 0.2, label = "This is some text")
read_pptx("~/Downloads/template.pptx") %>%
add_slide(layout = "Title and Content") %>%
ph_with(p, location = ph_location_type("body", id = 1)) %>%
add_slide(layout = "text_example") %>%
ph_with(p, location = ph_location_type("body", id = 1)) %>%
print("~/Desktop/test_example.pptx")
Where template.pptx is a copy of the officer template with the "Title and Content" slide duplicated (and named "test_example") and content box shrunken down a little bit (available here for reproducibility).
The first slide looks good, like this:, but the second slide has the dimensions of the plot shrunken while the content in the plot stays the same size, giving it a "squished" feel:
Has anyone run into this before? Are there any tricks/hacks out there that can tell my plot to decrease the size of all it's elements when the total image space is decreased? I'd like to maintain the relative size of the elements of the plot as I move to different slide templates.
If you're still here - THANK YOU FOR READING SO FAR! I'd appreciate any and all tips :)
Here is the code that would avoid that problem with officer version 0.3.14 or later (I haven't update my package for a while and officer is an on-going package)
For better quality plot with smaller size using vector graphic instead. Using package rvg
library(rvg)
library(gridExtra)
document %<>%
add_slide(layout = "text_example") %>%
# add the plot in at position relative to 1 inches top left
# with size is 6 inches square
# grid.arrange is just a code for generate plot not actually arrange anything
ph_with(value = dml(code = grid.arrange(plot), bg = "transparent"),
location = ph_location(left=1, top=1, width=6,
height=6, bg="transparent")) %>%
# Add a text box on the right side of the slide with certain
# size & colors
ph_with(value = block_list(fpar(ftext(" "))),
location = ph_location(left=6.11, top=1, width=3.73,
height=3.3, bg="#C6D9F1"))
I would recommend this when working with Powerpoint otherwise, you need to adjust template in Powerpoint and remember the order of each content container in that slide

Automatically adjust plot title width using ggplot

I am fairly new to R/ggplot2 and still learning on the go. Hopefully I am not missing something obvious!
I am trying to create several different plots using ggplot2 that I am layouting using the function plot_grid from the cowplot package to make the plots visible side by side and add plot numeration and captions. The problem is that if the generated plots are displayed in a small window or I have many plots beside one another then the titles of the two plots sometimes overlap. To solve this problem I tried to automatically insert line breaks in my too long titles using code I found in another thread since I wanted the text size of the titles to stay constant.
Using the following code I can easily automatically insert the necessary line breaks to make my title a specific width, but the problem is that I always need to enter a numeric value for the width. Depending on the number of plots I am inserting this value would of course change. I could of course go through my code and manually set the width for each set of plots until it is the correct value, but I was hoping to automate this process so that the title width is adjusted automatically to match the width of the x-axis. Is there anyway to implement this in R?
#automatically line break and add titles
myplot_theme1 = function (plot, x.title = NULL, y.title = NULL, plot.title = NULL) {
plot +
labs(title = paste(strwrap(plot.title, width = 50), collapse = "\n"),
x = x.title,
y = y.title)
}
# generate an example plot
data_plot <- data.frame(x = rnorm(1000), y = rnorm (1000))
plot1 <- ggplot(data_plot, aes(x = x, y = y)) + geom_point()
title <- "This is a title that is very long and does not display nicely"
myplot_theme1(plot1, plot.title = title)
My test plot
I have tried searching but I haven't found any solutions that seem to address what I am looking for. The only solution I did find that looked promising was based on the package gridDebug. This packages doesn't seem to be supported by my operating system anymore though (macOS Sierra Version 10.12.6) since when I try to install it I get the following error message:
Warning in install.packages: dependencies ‘graph’, ‘Rgraphviz’ are not available
And on the CRAN package documentation it states that the package is not even available for macOS El Capitan which was my previous operating system. If someone knows what is causing this issue so that I could try the solution from the above thread that would of course be great as well.
One idea (but perhaps not an ideal solution) is to adjust the size of text based on the number of characters in the title. You can adjust ggplot properties using theme and in this case you want to adjust plot.title (the theme property, not your variable). plot.title has elements size and horizontal justification hjust, the latter is in range [0,1].
# generate an example plot
data_plot <- data.frame(x = rnorm(1000), y = rnorm (1000))
plot1 <- ggplot(data_plot, aes(x = x, y = y)) + geom_point()
title1 <- "This is a title that is very long and does not display nicely"
title2 <- "I'm an even longer sentence just test me out and see if I display the way you want or you'll be sorry"
myplot_theme1 = function (plot, x.title = NULL, y.title = NULL, plot.title = NULL) {
plot +
labs(title = plot.title,
x = x.title,
y = y.title) +
theme(plot.title = element_text(size=800/nchar(plot.title), hjust=0.5)) # 800 is arbitrarily chosen
}
myplot_theme1(plot1, plot.title = title1)
myplot_theme1(plot1, plot.title = title2)

A library that outputs HTML grobs compatible with R's grid graphics?

I love Yihui's knitr package, and I know from the tutorials that it can put R into html documents. I want to go the other way -- I want to put some html into a grid graphics object. Is that possible in knitr, or any other library? Specifically, I am looking for a way to:
Style text using HTML (basic css and tables, mostly)
Wrap it up in a grob
Arrange/insert the grob using grid graphics, combining it with other grobs (ggplot charts, etc.)
I've searched on the knitr list and looked into grid graphics. It has a textGrob function but formatting options aren't robust enough for what I am looking for. There's a SO question that's in the ballpark but doesn't cover what I'm looking for. Here's a silly reproducible example that imitates the structure of my real document.
library(gridExtra)
#minimal valid object
rect = rectGrob()
text1 <- textGrob(
label = "textGrobs let you write text"
,x = unit(0.5, "npc"), y = unit(0.5, "npc")
,just = "centre"
,gp = gpar(col = "black", fontsize = 12)
)
text2 <- textGrob(
label = "but is there a graphics object that takes HTML?"
,x = unit(0.5, "npc"), y = unit(0.5, "npc")
,just = "centre"
,gp = gpar(col = "black", fontsize = 12)
)
#first split the box
top_box <- arrangeGrob(text1, text2, ncol = 2)
#put that together into a column
left_column <- arrangeGrob(
top_box, rect, rect
,nrow = 3
,heights = c(1, 2, 2)
)
grid.arrange(left_column, rect, widths = c(4/5, 1/5), ncol = 2)
I'd like to replace one of those empty rectangular grobs below with some text with HTML.
Thanks!
It's not clear what you mean by "an HTML grob". There is no HTML formatted object in your code. Certainly there are functions that can produce HTML and you could send that text to a grid.text call and display the HTML. I worry, however, that you intend to have some package display the HTML browser-like as a formatted table. The html function in Hmisc sends its output to a real browser. latex in Hmisc is designed for display. The tableGrob function in 'gridExtra' won't take HTML as a formatting specification. You might get further by examining the code and experimenting with xtable and print.xtable in the xtable package, since it is capable of delivering HTML output. You can also explore the latexTabular function in 'Hmisc' or the tabular function in the 'tables' package.

Resources