sactyr
sactyr

Reputation: 429

Embed images in plotly tick labels

I would like to embed images as part of x axis in a plotly chart (not in place of x axis). Code of what I have tried:

library(plotly)
library(dplyr)
library(tidyr)

Animals <- c("giraffes", "orangutans", "monkeys")
SF_Zoo <- c(20, 14, 23)
LA_Zoo <- c(12, 18, 29)
data <- data.frame(Animals, SF_Zoo, LA_Zoo) %>% 
  pivot_longer(cols = c(SF_Zoo, LA_Zoo)) %>% 
  mutate(Animals = paste(Animals, "<img src='https://images.plot.ly/language-icons/api-home/r-logo.png'</img>"))


plot_ly(data, x = ~Animals, y = ~value, type = 'bar', color = ~name) %>%
  layout(
    barmode = "stack"
  )

Image from code above

As can be seen the img tags get printed as literal string. I have tried wrapping tick labels Animals with htmltools::HTML but no joy.

This plotly guide talks about embedding images/logos within the plot area, but I would like to embed images as part of the tick labels. And this python SO solution replaces the tick labels with images entirely.

Upvotes: 0

Views: 48

Answers (2)

Tim G
Tim G

Reputation: 4147

Just like in the python answer, you can paste the images into the layout iterating over the x-values of your data. For this you could use lapply to build the image-list. Use xref = "x" as described here. I would also create some space below the plot for the images using margin = list(b = 150), but you could also push them to a background layer using layer="below". You can then use xanchor = "center" to always center the images.

out

Code

library(plotly)
library(dplyr)
library(tidyr)

Animals <- c("giraffes", "orangutans", "monkeys")
imgs <- c(
  "https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg",
  "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRfPhPFLZSG51k0T3Mg0m8EWmek_sDLO9LsAh8kbVoOkzVHFKdAsbZmY4xfaIMVFq4uxcUKWV8LkS8D_nwK2AsTmA",
  "https://cdn.mos.cms.futurecdn.net/ZRAWdgHeNNPw8PaSxg7kVj-1200-80.jpg"
)

SF_Zoo <- c(20, 14, 23)
LA_Zoo <- c(12, 18, 29)
data <- data.frame(Animals, SF_Zoo, LA_Zoo) %>% 
  pivot_longer(cols = c(SF_Zoo, LA_Zoo))

img_list <- lapply(seq_along(Animals), function(i, size = 0.4) {
  list(
    source = imgs[i],  
    xref = "x",       
    yref = "paper",   
    x = Animals[i],   
    y = -0.15,        
    sizex = size, sizey = size,
    xanchor = "center"
  )
})

plot_ly(data, x = ~Animals, y = ~value, type = 'bar', color = ~name) %>%
  layout(
    barmode = "stack",
    images = img_list,
    margin = list(b = 150) # adjust bottom margin
  )

Upvotes: 1

Nipuna Upeksha
Nipuna Upeksha

Reputation: 428

Unfortunately, unlike Plotly in Python, R does not directly support embedding images inside tick labels. However, we can achieve this effect using background images and manual positioning.

The following code adds the images you need, but you may want to change the parameters of the images object to add them properly to your graph.

library(plotly)
library(dplyr)
library(tidyr)

# Sample data
Animals <- c("Giraffes", "Orangutans", "Monkeys")
SF_Zoo <- c(20, 14, 23)
LA_Zoo <- c(12, 18, 29)

# Convert data to long format
data <- data.frame(Animals, SF_Zoo, LA_Zoo) %>% 
  pivot_longer(cols = c(SF_Zoo, LA_Zoo))

# Create the bar chart
p <- plot_ly(data, x = ~Animals, y = ~value, type = 'bar', color = ~name) %>%
  layout(
    barmode = "stack",
    xaxis = list(title = "Animals", tickvals = c(0, 1, 2), ticktext = Animals),
    images = list(
      list(source = "https://images.plot.ly/language-icons/api-home/python-logo.png",
           xref = "paper",
           yref = "paper",
           x= 0,
           y= 0,
           sizex = 0.1,
           sizey = 0.1,
           opacity = 0.8
      ),
      
      list(source = "https://images.plot.ly/language-icons/api-home/matlab-logo.png",
           xref = "x",
           yref = "paper",
           x = 1,
           y = 0,
           sizex = 0.2,
           sizey = 0.2,
           opacity = 0.8z
      ),
      
      list(source =  "https://images.plot.ly/language-icons/api-home/python-logo.png",
           xref = "x",
           yref = "paper",
           x = 1.5,
           y = 0,
           sizex = 0.1,
           sizey = 0.1,
           sizing = "stretch",
           opacity = 0.8
      )
    )
  )

# Display the plot
p

result

Upvotes: 1

Related Questions