How to get output having text displayed on image using r markdown

Can anyone help with the code to display text on image as an output? Please help with the R code.

Please let us know what you already did so far.
Did you create an image in R and now you want to 'annotate' it with some text?
Or do want to create an image that contains only a text?
And why would you want to do this with rmarkdown?

I have creates a inline codes to get the report on word doc. Now I want to display the output on a template which is an image. The purpose is to automate the reporting. Can you please help regarding the same?

Please show us a simple example of the code you used to produce your output
There is no need to use actual data: use some random strings and numbers.
Also show us the template (that is an image as I understand) and tell us what format is has:
a jpeg- or a pdf-file ?

EDIT: is this related to an earlier question :
https://forum.posit.co/t/showing-images-in-using-ifelse-condition-in-r-markdown/141648
?

Below is the sample code that I am trying to run - if the output is possible on any image then please let me know how to do it.

title: "Untitled"
author: "Karan Sehgal"
date: "r Sys.Date()"
output: word_document

library(readxl) 
library(dplyr)

data = read_xlsx(choose.files())
#Account-wise TCV aggregation
agg_tcv_account = data%>%group_by(`Account Name`)%>%summarise(tcv= sum(`TCV Value`))

#Total value of SS2

total_ss2_val = data%>%subset(`Sales Stage`== "SS1")%>%select(`TCV Value`)%>%sum()
total_ss1_val = data%>%subset(`Sales Stage`=="SS2")%>%select(`TCV Value`)%>%sum()
Total_d_val = data%>%subset(`Account Name`== "a")%>%select(`TCV Value`)%>%sum()


Below is the output that I want with in the template which is an Image -----

Sales Stage Insights

  1. The value of deals in Sales Stage 2 is r total_ss2_val.
  2. The value of deals in Sales Stage 1 is r total_ss1_val.
  3. Total value of Account D is r Total_d_val

Account-wise TCV aggregation

library(knitr)

table1 = kable(agg_tcv_account)
table1

I want the below visual also on the right hand side of the above out - basically want to position it on the template which is an Image.

Plot


plot1=ggplot(data) +
 aes(x = `Sales Stage`, y = `TCV Value`, fill = `Account Name`) +
 geom_col() +
 scale_fill_hue(direction = 1) +
 theme_minimal()
plot1

It is still not clear to me what you precisely want to do.
You include an Rmd-file (when doing so use four backticks!) producing a doc-file
However I would not know how to edit and position an image.
For editing an image you could the package magick and afterwards include that image in your doc file. As I said I am not sure which (if any) control you then have over the placement/positioning of images.
In the remainder of this post I first include my version of the Rmd file (with the four backticks) and after that an example of the use of magick to annotate your graph. Placement of annotations should be changed of course.

Rmd-file (this line should be removed)
---
title: "Untitled"
author: "My name"
date: '2022-07-15'
output: word_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
#library(readxl) 
library(dplyr)
library(knitr)
library(ggplot2)
```

```{r}
# data = read_xlsx(choose.files())
data <- tibble::tribble(
  ~`Account Name` , ~`Sales Stage`, ~`TCV Value` ,
  "a" ,"SS1", 314,
  "a" ,"SS1", 271,
  "a" ,"SS2", 600, 
  "b" ,"SS1", 414,
  "b" ,"SS1", 371,
  "b" ,"SS2", 700,
)
#Account-wise TCV aggregation
agg_tcv_account = data%>%group_by(`Account Name`)%>%summarise(tcv= sum(`TCV Value`))

#Total value of SS2

total_ss1_val = data%>%subset(`Sales Stage`== "SS1")%>%select(`TCV Value`)%>%sum()
total_ss2_val = data%>%subset(`Sales Stage`=="SS2")%>%select(`TCV Value`)%>%sum()
Total_d_val = data%>%subset(`Account Name`== "a")%>%select(`TCV Value`)%>%sum()

```

## Results

*Sales Stage Insights*

The value of deals in Sales Stage 2 is `r total_ss2_val`.  
The value of deals in Sales Stage 1 is `r total_ss1_val`.  
Total value of Account D is `r Total_d_val`


```{r table}

table1 = kable(agg_tcv_account)
table1
```
```{r plot}
plot1=ggplot(data) +
 aes(x = `Sales Stage`, y = `TCV Value`, fill = `Account Name`) +
 geom_col() +
 scale_fill_hue(direction = 1) +
 theme_minimal()
plot1
```

R-file that uses Magick (this line should be removed)
#library(readxl) 
library(dplyr)
#> Warning: package 'dplyr' was built under R version 4.1.2
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(ggplot2)
library(magick)
#> Linking to ImageMagick 6.9.12.3
#> Enabled features: cairo, freetype, fftw, ghostscript, heic, lcms, pango, raw, rsvg, webp
#> Disabled features: fontconfig, x11

# data = read_xlsx(choose.files())
data <- tibble::tribble(
  ~`Account Name` , ~`Sales Stage`, ~`TCV Value` ,
  "a" ,"SS1", 314,
  "a" ,"SS1", 271,
  "a" ,"SS2", 600, 
  "b" ,"SS1", 414,
  "b" ,"SS1", 371,
  "b" ,"SS2", 700,
)

plot1=ggplot(data) +
 aes(x = `Sales Stage`, y = `TCV Value`, fill = `Account Name`) +
 geom_col() +
 scale_fill_hue(direction = 1) +
 theme_minimal()

ggsave("myplot1.jpeg")
#> Saving 7 x 5 in image

total_ss1_val = data%>%subset(`Sales Stage`== "SS1")%>%select(`TCV Value`)%>%sum()
total_ss2_val = data%>%subset(`Sales Stage`=="SS2")%>%select(`TCV Value`)%>%sum()
Total_d_val = data%>%subset(`Account Name`== "a")%>%select(`TCV Value`)%>%sum()

p1 <- "Sales Stage Insights"
p2 <- paste("The value of deals in Sales Stage 2 is", total_ss2_val,".") 
p3 <- paste("The value of deals in Sales Stage 1 is", total_ss1_val,".") 
p4 <- paste("Total value of Account D is", Total_d_val,".") 
p1234 <- c(p1,p2,p3,p4)

my_annotate <- function(text, x, y, size, color="white", bg.color="black",
                         family="Lato Black", bg.r=0.06, fontface=2) {
  annotate("text", label=text, x=x, y=y,size=size,
           color="blue", # bg.color=bg.color,
           family=family, # bg.r=bg.r,
           fontface=fontface)
}

im     <- image_read("myplot1.jpeg")
iminfo <- image_info(im)
# str(iminfo)
# tibble [1 x 7] (S3: tbl_df/tbl/data.frame)
# $ format    : chr "JPEG"
# $ width     : int 2100
# $ height    : int 2100
# $ colorspace: chr "sRGB"
# $ matte     : logi FALSE
# $ filesize  : int 113743
# $ density   : chr "300x300"
width  <- pull(iminfo, "width")
height <- pull(iminfo, "height")
# device that will contain variable data
fig    <-
  image_graph(width = width, height = height, bg = "transparent")
# empty plot that will contain variable data
p <- ggplot() + xlim(0, width) + ylim(0, height) + theme_void()

for (i in 1:4) {
  p <- p + my_annotate(p1234[i], width / 2 - 600 , height / 2 - i*60, 12)
}
print(p)
dev.off()
#> png 
#>   2
out <- image_composite(im, fig, operator = 'Over')
image_write(out, "total.jpeg")
Created on 2022-07-15 by the reprex package (v2.0.1)

Thanks very much, this is what I needed. Also, 1 more thing. If I want to change the position of 1st statement to be displayed on top of image, 2nd statement on left side of image and the last statement on right side of the image. What are the changes required in the coding for the same?

Positioning is done by specifying the x and y coordinates in the annotate function.
As an example I indicate the corner-coordinates in the plot in the following way:

p <- p + annotate("text",label="(0,0)",color="red",x=0+15,y=0+15,size=12)
p <- p + annotate("text",label="(2100,0)",color="red",x=2100-15,y=0+15,size=12)
p <- p + annotate("text",label="(0,2100)",color="red",x=0+15,y=2100-15,size=12)
p <- p + annotate("text",label="(2100,2100)",color="red",x=2100-15,y=2100-15,size=12)

Notes:

  • I added/subtracted 15 to stay some distance away from the actual corner points
  • the coordinates specify the center/midpoint of the string (as can be seen from the blue texts that all have the same x coordinate)
  • for the exact positioning I think you have to experiment with the x- and y-coordinates and size
  • in the first example I used the function my_annotate derived from ggplot2::annotate and now I use the latter function directly.

1 Like

Thank you so much, this is really helpful..

1 Like

This topic was automatically closed 21 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.