2

Consider the following R snippet to render a heatmap with categorical axes:

library(plotly)

x <- c("Blue", "Red")
y <- c("One", "Two")

plot_ly(x = x, y = y, z = c(1:4)) %>%
    add_heatmap(
        opacity = 0.9
    ) %>%
    add_annotations(
        text = c(1:4),
        showarrow = FALSE
    )

This renders the following heatmap: enter image description here

The annotations appear to be distributed diagonally and unevenly, starting from the bottom left cell. 1 and 3 are in the bottom left cell, and 2 and 4 in the upper right. Why is this? How should my annotation text be structured for it to be ordered more intuitively (horizontally or vertically)?

Maximilian Peters
  • 30,348
  • 12
  • 86
  • 99
Justin Sleep
  • 55
  • 1
  • 6
  • Welcome to Stackoverflow! Your chances of getting an answer are much higher if you provide a [MCVE]. In your case, give us the values of `corrs`. – Maximilian Peters May 09 '18 at 19:13
  • Hi Maximilian, and thanks for the welcome! Sorry about omitting corrs, I didn't think the contents were relevant when I posted. I've updated the OP to include the contents of the data frame. – Justin Sleep May 09 '18 at 20:33
  • No worries! Here is a great thread for R question on Stackoverflow: https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – Maximilian Peters May 09 '18 at 20:53
  • Thanks, Max. I've updated the example in my question to be more minimal and easily reproduced. – Justin Sleep May 10 '18 at 02:17

1 Answers1

2

I can only speculate about the problem but in the provided image you can see that Plotly only used two values out of the 4 z-values. Your colorscale on the right goes from 1 to 2, not 1 to 4. This happens mMost likely because you provided only two x and y values.

  • Use a data frame

    df <- expand.grid(x, y)
    df <- transform(df, text = paste(Var1, Var2, sep='_'))
    
    print(df)
    
    Var1 Var2     text
    1 Blue  One Blue_One
    2  Red  One  Red_One
    3 Blue  Two Blue_Two
    4  Red  Two  Red_Two
    
  • You can now easily use add_annotations

    add_annotations(x = df$Var1,
                    y = df$Var2,
                    text = df$text)
    

To get the following plot enter image description here

Complete code

library(plotly)

x <- c("Blue", "Red")
y <- c("One", "Two")
df <- expand.grid(x, y)
df <- transform(df, text = paste(Var1, Var2, sep='_'))

p <- plot_ly(x = df$Var1, 
             y = df$Var2, 
             z = c(1:4)
             ) %>%
  add_heatmap(opacity = 0.9
              ) %>% 
  add_annotations(x = df$Var1,
                  y = df$Var2,
                  text = df$text)

p

Alternatively you could loop over your values and add an annotation for each one.

library(plotly)

x <- c("Blue", "Red")
y <- c("One", "Two")

p <- plot_ly(x = x, 
             y = y, 
             z = c(1:4)
             ) %>%
  add_heatmap(opacity = 0.9)

for (val_x in x)
{
  for (val_y in y)
  {
    p <- add_annotations(p, 
                         x = val_x,
                         y = val_y,
                         text = paste(val_x, val_y, sep = '_'))
  }
}

p

enter image description here

Maximilian Peters
  • 30,348
  • 12
  • 86
  • 99
  • Thanks, Maximilian! Your answer pointed me in the right direction. I ended up using melt() from the reshape library to create the annotations to pass in. – Justin Sleep May 10 '18 at 12:08