Plot_ly 在 R 中:如何在图例中包含颜色栏、符号和标记的大小?

Plot_ly in R: How to include a colorbar, symbols and the size of markers in a legend?

我有一个散点图,数据点位于坐标“test_Xn”和“test_Yn”。

有关这些数据点的附加信息存储在数据框“test_data”的“Item_1”、“Item_2”和“Item_3”列中:

library(plotly)
test_Xn <- c(13, 7, 12, -7, -9, 8)
test_Yn <- c(3, -0.5, 6, 3, 11, 5)
test_data <- data.frame("Item_1"= c(2.6, 2.6, 1.6, 3.2, NA, 1.8), # scale: 1 to 6
                        "Item_2"= c(2.7, 1.8, 2.2, 2.8, 3.2, 2), # scale: 1 to 4
                        "Item_3"= c(1, 2, 1, 2, 1, 1)) # values: 1 or 2

除了悬停信息之外,为了可视化附加信息,还使用了不同颜色、符号或大小的标记:

    test <- plotly::plot_ly(x = ~test_Xn, y = ~test_Yn, mode = "markers",
                        text = paste("<b>Item_1: </b>", test_data$Item_1,
                                     "<b>\nItem2: </b>", test_data$Item_2,
                                     "<b>\nItem2: </b>", test_data$Item_3),
                        hoverinfo = "text", 
                        marker = list(sizemode = "diameter",
                                      color = test_data[["Item_1"]],
                                      cmin = 1, cmax = 6,
                                      colorbar = list(titel = "Item_1",
                                                      xanchor = "left",
                                                      yanchor = "middle"),
                                      colorscale = "Viridis",
                                      size = ~ test_data[["Item_2"]]*25,
                                      symbol = ~ test_data[["Item_3"]]))

test_axis <- list(titel="", showgrid=T, showticklabels=T, zeroline=F)

test_plot <- plotly::layout(test, xaxis=test_axis, yaxis=test_axis)

print(test_plot)

上面的代码产生了以下情节:

不幸的是,我只能将颜色条(缩放)作为图例的一部分。在过去的几天里,我无法找到同时将标记的大小(缩放)和标记的符号作为图例和情节的一部分的解决方案,但我相信一定有一个解决方案。

提前致谢。

您需要通过这种方式为图例使用子图:

library(plotly)
library(dplyr)

### Data ----
test_Xn <- c(13, 7, 12, -7, -9, 8)
test_Yn <- c(3, -0.5, 6, 3, 11, 5)
test_data <- data.frame("Item_1"= c(2.6, 2.6, 1.6, 3.2, NA, 1.8), # scale from 1 to 6
                        "Item_2"= c(2.7, 1.8, 2.2, 2.8, 3.2, 2), # scale from 1 to 4
                        "Item_3"= c(1, 2, 1, 2, 1, 1)) # values 1 or 2


### Main plot ----
main.plot <-
  plot_ly(type='scatter',
          mode="markers",
          # X and Y
          x=~test_Xn,
          y=~test_Yn,
          # Text on hover
          text = paste("<b>Item_1: </b>", test_data$Item_1,
                       "<b>\nItem2: </b>", test_data$Item_2,
                       "<b>\nItem2: </b>", test_data$Item_3),
          hoverinfo = "text",
          # Marker
          marker=list(
            sizemode = "diameter",
            # Color scale
            color = test_data[["Item_1"]],
            cmin = 1, cmax = 6,
            colorbar = list(
              title = list(text='<b>Item_1</b>'),
              xanchor = "left",
              yanchor = "middle"
            ),
            colorscale = "Viridis",
            size = ~ test_data[["Item_2"]]*25,
            symbol = ~ test_data[["Item_3"]]
          ),
          showlegend=T
  ) %>% 
  layout(
    xaxis=list(titel="", showgrid=T, showticklabels=T, zeroline = F, showline= T, linewidth=2, linecolor='grey', mirror = T),
    yaxis=list(titel="", showgrid=T, showticklabels=T, zeroline = F, showline= T, linewidth=2, linecolor='grey', mirror = T),
    legend = list(
      traceorder="grouped"
    )
  )

main.plot



### Legend plots :

### For size ----
# Number of different sizes to show in size legend :
numbersize = 4

size.legend.plot <- plot_ly() %>% 
  add_markers(
    x = 1, 
    y = 1:numbersize,
    # Choose symbol : You can keep it circle here if you want, or choose between : c('circle', 'square', 'x', 'triangle')
    symbol = 1:4,
    symbols = rep("square",length(1:numbersize)),
    size = 1:4,
    showlegend = F,
    # disable hover
    hoverinfo="none",
    marker = list(sizeref=0.1,sizemode="area",
                  color = "#7C7C7C")
  )%>%
  layout(
    annotations = 
      list(
        list(
          x = 1, 
          y = 1, 
          text = "<b> Item_2</b>", 
          showarrow = F, 
          xref='paper', 
          yref='paper')),
    xaxis = 
      list(
      zeroline=F,
      showline=F,
      showticklabels=F,
      showgrid=F),
    yaxis=
      list(
        showgrid=F,
        tickmode = "array",
        tickvals = 1:4,
        ticktext = 1:4
      )
  )

# This legend looks like:
size.legend.plot

## Now, we can merge the two legends
subplot(main.plot, size.legend.plot, widths = c(0.90, 0.10), 
        titleX=TRUE, titleY=TRUE)

# We go for the second legend in the same analogy

### Legend for symbols
# Choose your vector of symbols:
symbol = 1:2

# plot for this legend : 
symbol.legend.plot <- plot_ly() %>% 
  add_trace(type = "scatter",
            x = 1, 
            y = symbol,
            symbol = ~symbol,
            mode = 'markers',
            showlegend = F,
            # disable hover
            hoverinfo="none",
            # Marker
            marker=list(
              sizemode = "diameter",
              # size = 0.5,
              symbol = ~symbol,
              color = "#7C7C7C",
              size = 28
            )
  )%>%
  layout(
         annotations = 
           list(
             list(
               # Localization of annotation : adjustment of x & y
               x = 0.5, 
               y = 1, 
               text = paste0("<b>",symbol[1],"</b>"),
               showarrow = F, 
               xref='paper', 
               yref='paper'),
             list(
               x = 0.5, 
               y = 0, 
               text = paste0("<b>",symbol[2],"</b>"), 
               showarrow = F, 
               xref='paper', 
               yref='paper')
           ),
         xaxis = 
           list(
             zeroline=F,
             showline=F,
             showticklabels=F,
             showgrid=F
           ),
         yaxis=
           list(
             zeroline=F,
             showline=F,
             showticklabels=F,
             showgrid=F
           )
  )

# looks like
symbol.legend.plot

### Put all together

# Adjust with parameters for the design you want
subplot(main.plot, symbol.legend.plot, size.legend.plot, widths = c(0.85,0.1, 0.05), 
        titleX=TRUE, titleY=TRUE)