简体   繁体   中英

Order alphabetically the entries of plotly legend in R

I create the plotly chart below which normally is in a shiny app so the selection of y variables is dynamic. In this case I have Bob and Anna . I want to modify the legend. The colors order is correct as I want the deeper blue to be on top but I want to stabilize the order that the names are displayed, probably alphabetically so Anna should always be displayed first with the deeper blue color in the legend. Remember that the selection is dynamic in a shiny app.

Week<-structure(c(18323, 18330, 18337, 18344, 18351, 18358, 18365, 
                  18372, 18379, 18386, 18393, 18400, 18407, 18414, 18421, 18428, 
                  18435, 18442, 18449, 18456, 18463, 18470, 18477, 18484, 18491, 
                  18498, 18505, 18512, 18519, 18526, 18533, 18540, 18547, 18554, 
                  18561, 18568, 18575, 18582, 18589, 18596, 18603, 18610, 18617, 
                  18624, 18631, 18638, 18645, 18652, 18659, 18666, 18673, 18680, 
                  18687, 18694, 18701, 18708, 18715, 18722, NA), class = "Date")

Bob<-c(NA, 12, 28, 89, 205, 311, 367, 419, 536, 673, 787, 996, 1501, 
       2091, 2836, 3971, 5429, 7422, 9653, 12205, 15096, 19962, 23567, 
       28432, 33051, 37347, 43390, 49897, 54851, 60913, 67073, 72769, 
       79629, 84063, 88398, 89579, 88464, 85595, 81697, 74943, 67632, 
       58226, 53371, 49759, 51508, 55515, 58813, 62240, 62627, 62646, 
       61285, 54438, 49614, 46721, 44554, 48151, 54014, 68891, 47176
)
Anna<-c(NA, 12, 28, 89, 205, 311, 367, 419, 536, 673, 787, 996, 1501, 
        2091, 2836, 3971, 5429, 7422, 9653, 12205, 15096, 19962, 23567, 
        28432, 33051, 37347, 43390, 49897, 54851, 60913, 67073, 72769, 
        79629, 84063, 88398, 89579, 88464, 85595, 81697, 74943, 67632, 
        58226, 53371, 49759, 51508, 55515, 58813, 62240, 62627, 62646, 
        61285, 54438, 49614, 46721, 44554, 48151, 54014, 68891, 47176
)*50


re<-data.frame(Week,Bob,Anna)

re<-re %>%   group_by(month_year = format(Week, '%Y-%b')) %>%   summarise(across(c(Bob,Anna), sum, na.rm  =TRUE))


colnames(re)[1]<-"Week"

ay <- list(
  overlaying = "y",
  side = "right",
  title = "Second",
)
tempNames <- c("Bob", "Anna")
tempNamesV2 <- tempNames[order(tempNames)]
# plotlyObjList <-
p <- plot_ly(re)
for(i in seq_along(tempNamesV2)){
  if(i == 1){
    p <- add_bars(p,  x = ~Week, y = re[[tempNamesV2[i]]], name = tempNamesV2[i], 
                  marker = list(color = "#3E5B84"), yaxis = "y", offsetgroup = i,
                  text = ~ paste("<b>Country:</b>", tempNamesV2[i], "<br><b>Date:</b>",Week ),
                  hovertemplate = paste('%{text}<extra></extra>'))
  } else if (i == 2){
    p <- add_bars(p,  x = ~Week, y = re[[tempNamesV2[i]]], name = tempNamesV2[i], 
                  marker = list(color = "#6BBABF"), yaxis = "y2", offsetgroup = i,
                  text = ~ paste("<b>Country:</b>", tempNamesV2[i], "<br><b>Date:</b>",Week ),
                  hovertemplate = paste('%{text}<extra></extra>'))
  }
}
p <- p %>% layout(yaxis2 = ay,
                  xaxis = list(title = "Date"),
                  yaxis = list(title = "i"),
                  margin = list(l=50,b = 100, t=50),
                  barmode = 'group',
                  legend=list(x = 1.05, y = 1,title=list(text='<b> Country </b>')))
p

You can use a loop to load the object after sorting it. I prefer using order() so I can extract the sort position for other uses, but a simple sort() is good. The legend for plotly is based on when you add_trace/add_bars to the plotly, the earlier one gets to the top position.

Since you only used 2 y's, I assume the user can only select up to 2 "Names" at a time, and you are trying to make sure the Countries are sorted:

Week<-structure(c(18323, 18330, 18337, 18344, 18351, 18358, 18365, 
                      18372, 18379, 18386, 18393, 18400, 18407, 18414, 18421, 18428, 
                      18435, 18442, 18449, 18456, 18463, 18470, 18477, 18484, 18491, 
                      18498, 18505, 18512, 18519, 18526, 18533, 18540, 18547, 18554, 
                      18561, 18568, 18575, 18582, 18589, 18596, 18603, 18610, 18617, 
                      18624, 18631, 18638, 18645, 18652, 18659, 18666, 18673, 18680, 
                      18687, 18694, 18701, 18708, 18715, 18722, NA), class = "Date")
    
Bob<-c(NA, 12, 28, 89, 205, 311, 367, 419, 536, 673, 787, 996, 1501, 
         2091, 2836, 3971, 5429, 7422, 9653, 12205, 15096, 19962, 23567, 
         28432, 33051, 37347, 43390, 49897, 54851, 60913, 67073, 72769, 
         79629, 84063, 88398, 89579, 88464, 85595, 81697, 74943, 67632, 
         58226, 53371, 49759, 51508, 55515, 58813, 62240, 62627, 62646, 
         61285, 54438, 49614, 46721, 44554, 48151, 54014, 68891, 47176
)
Anna<-c(NA, 12, 28, 89, 205, 311, 367, 419, 536, 673, 787, 996, 1501, 
          2091, 2836, 3971, 5429, 7422, 9653, 12205, 15096, 19962, 23567, 
          28432, 33051, 37347, 43390, 49897, 54851, 60913, 67073, 72769, 
          79629, 84063, 88398, 89579, 88464, 85595, 81697, 74943, 67632, 
          58226, 53371, 49759, 51508, 55515, 58813, 62240, 62627, 62646, 
          61285, 54438, 49614, 46721, 44554, 48151, 54014, 68891, 47176
)*50


re<-data.frame(Week,Bob,Anna)

re<-re %>%   group_by(month_year = format(Week, '%Y-%b')) %>%   summarise(across(c(Bob,Anna), sum, na.rm  =TRUE))


colnames(re)[1]<-"Week"

ay <- list(
  overlaying = "y",
  side = "right",
  title = "Second"
)
tempNames <- c("Bob", "Anna")
tempNamesV2 <- tempNames[order(tempNames)]
p <- plot_ly(re)
for(i in seq_along(tempNamesV2)){
  if(i == 1){
      p <- add_bars(p,  x = ~Week, y = re[[tempNamesV2[i]]], name = tempNamesV2[i], 
                marker = list(color = "#3E5B84"), yaxis = "y", offsetgroup = i,
                text = ~ paste("<b>Country:</b>", tempNames[i], "<br><b>Date:</b>",Week ),
                hovertemplate = paste('%{text}<extra></extra>'))
  } else if (i == 2){
      p <- add_bars(p,  x = ~Week, y = re[[tempNamesV2[i]]], name = tempNamesV2[i], 
                marker = list(color = "#6BBABF"), yaxis = "y2", offsetgroup = i,
                text = ~ paste("<b>Country:</b>", tempNames[i], "<br><b>Date:</b>",Week ),
                hovertemplate = paste('%{text}<extra></extra>'))
  }
}
p

用正确的悬停更新了绘图

I also realized you have two margins in the layout, and I put them together.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM