1

Hello and thanks in advance, I am looking for a way to implement background images in my treemap and, ideally, automatically adjust the color of the text to the colors of the background image, just like plotly does when there is only background. I have so far tried with Plotly, ECharts, ggplot2, and have not been able to find any way to succeed. I found the "add_trace(x, type="image")" in Plotly, but could not locate any examples online on how to use it with treemap.

Here is an example code:

treemap <- data.frame(names = c("Bob", "Rob", "Knob", "Pam", "Sam"), n = c(13, 44, 1, 22, 9))
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Orson
  • 23
  • 3

1 Answers1

1

Since it looks like you're new to SO--welcome to the community! If you want great answers quickly, it's best to make your question reproducible. This includes sample data like the output from dput() or reprex::reprex() and any libraries you are using. (The data you provided isn't complete; what about the images?) When you've tried but haven't been successful, you need to include the code that did not work (not a list of libraries). We're all about helping you with code, not doing it for you... Check it out: making R reproducible questions.

After my explanation, I'll provide the same code again altogether (much easier copy + paste).

Within this answer, I've used the highcharter, tidywikidatar and tidyverse libraries.

Here's the plan I followed.

  1. collect some data
  2. prepare data for treemap
  3. make a plain treemap to ensure data setup is correct
  4. collect images to use in treemap
  5. recreate treemap with images, check for form, fit and function

Step 1 get some data

library(tidyverse)
library(highcharter)
library(tidywikidatar)

data("mpg")

funModeling::df_status(mpg) # what data do we have? --simplify for example
mpg2 <- mpg %>% filter(manufacturer %in% unique(mpg$manufacturer)[3:5]) %>% 
  mutate(model = stringr::str_to_sentence(model)) # change from all small letters

Step 2 prep data

# prepare data for treemap
dout <- data_to_hierarchical(mpg2, c(manufacturer, model), cty)

Step 3 inspect what I expect

hchart(dout, type = "treemap")  # validate the structure before adding images

Step 4 collect images to use

This step has several substeps.

Collect image data, using mpg data and Wikipedia

  1. create search terms
  2. collect image URLs from Wikipedia
  3. add to dout (the data used in the original treemap)
#  1) create search terms 
mods <- mpg2[, c(1, 2), ] %>% 
  mutate(imgN = paste0(manufacturer, "_", strsplit(model, " ") %>% map_chr(., 1)))

mods2 <- mods[!duplicated(mods), ] # only one image per 'square'

#  2) collect image URLs from Wikipedia 
mods3 <- lapply(1:nrow(mods2), function(i) {
  ids <- tidywikidatar:::tw_search_single(mods2[i, 3], limit = 1) # find picture IDs
  urls <- tw_get_image(id = ids, format = "embed")[1, 2]          # use Ids to get image
  data.frame(mods2[i, 1], mods2[i, 2], mods2[i, 3], urls)         # add to dataframe
}) %>% list_rbind() # return data frame (not list)


#  3) add to dout
invisible(lapply(1:length(dout), function(k) {
  if(any(names(dout[[k]]) %in% "parent")) {                       # find children 
    wh <- filter(mods3, manufacturer == dout[[k]]$parent,         # id correct URL
                 model == dout[[k]]$name)
                                                        # add encoded url to dout 
    dout[[k]]$color <<- list(pattern = list(image = URLencode(unlist(wh$image)),
                                            aspectRatio = 1/1))
  }
}))

Step 5 recreate the treemap with images

hchart(dout, type = "treemap") %>% 
  hc_add_dependency("modules/pattern-fill.js") # necessary plugin to add images

enter image description here

It's really hard to read the labels, so I wanted to modify them. I've only used a few of the many parameters available. You can read about all of the possibilities here.

# Hard to read labels, can be adjusted a variety of ways
hchart(dout, type = "treemap", dataLabels = list(
  backgroundColor = "black", borderWidth = 2,
  style = list(color = "yellow", fontSize = "15px"))) %>% 
  hc_add_dependency("modules/pattern-fill.js") # necessary plugin to add images

enter image description here

All that code altogether

library(tidyverse)
library(highcharter)
library(tidywikidatar)

data("mpg")

funModeling::df_status(mpg) # what data do we have? --simplify for example
mpg2 <- mpg %>% filter(manufacturer %in% unique(mpg$manufacturer)[3:5]) %>% 
  mutate(model = stringr::str_to_sentence(model)) # change from all small letters

# prepare data for treemap
dout <- data_to_hierarchical(mpg2, c(manufacturer, model), cty)

hchart(dout, type = "treemap")  # validate the structure before adding images

# collect image data, using mpg data dn Wikipedia
#  1) create search terms 
#  2) collect image URLs from Wikipedia 
#  3) add to dout

#  1) create search terms 
mods <- mpg2[, c(1, 2), ] %>% 
  mutate(imgN = paste0(manufacturer, "_", strsplit(model, " ") %>% map_chr(., 1)))

mods2 <- mods[!duplicated(mods), ] # only one image per 'square'

#  2) collect image URLs from Wikipedia 
mods3 <- lapply(1:nrow(mods2), function(i) {
  ids <- tidywikidatar:::tw_search_single(mods2[i, 3], limit = 1) # find picture IDs
  urls <- tw_get_image(id = ids, format = "embed")[1, 2]          # use Ids to get image
  data.frame(mods2[i, 1], mods2[i, 2], mods2[i, 3], urls)         # add to dataframe
}) %>% list_rbind() # return data frame (not list)


#  3) add to dout
invisible(lapply(1:length(dout), function(k) {
  if(any(names(dout[[k]]) %in% "parent")) {                       # find children 
    wh <- filter(mods3, manufacturer == dout[[k]]$parent,         # id correct URL
                 model == dout[[k]]$name)
                                                                  # add url to dout 
    dout[[k]]$color <<- list(pattern = list(image = URLencode(unlist(wh$image)),
                                            aspectRatio = 1/1))
  }
}))


# recreate treemap
hchart(dout, type = "treemap") %>% 
  hc_add_dependency("modules/pattern-fill.js") # necessary plugin to add images


# Hard to read labels, can be adjusted a variety of ways
hchart(dout, type = "treemap", dataLabels = list(
  backgroundColor = "black", borderWidth = 2,
  style = list(color = "yellow", fontSize = "15px"))) %>% 
  hc_add_dependency("modules/pattern-fill.js") # necessary plugin to add images
Kat
  • 15,669
  • 3
  • 18
  • 51
  • 1
    Haven't heard of this package before, it works perfectly! And it's elegant, too. Thank you very much! – Orson Aug 27 '23 at 22:24