plotly R graph - 标记符号不显示在图例中,除非添加段跟踪

plotly R graph - marker symbol doesn't show in legend unless segment trace is added

我有一个包含以下内容的绘图: - 线图,其中删失值绘制为空心圆,非删失数据集点为实心。 - 在某些图表中将显示趋势线(使用 add_segment 添加)

未添加趋势线时,我似乎无法显示标记图例。

理想情况下,我只希望 'censored datapoints' 出现在图例中,因此我为标记添加了两条轨迹(一条用于截尾,showlegend = TRUE,另一条用于 showlegend = FALSE)。不确定是否有另一种方法可以做到这一点 - plot_ly.

非常新
# datasets
results <- structure(list(slope = 0, slope_p_val = 0.672652383888971, int_from_data = 0.06, 
    pct_cens = 9.3, annual_slope_units = 0, sigclass = "No evidence of trend", 
    sig = structure(2L, .Label = c("Significant", "Not significant"
    ), class = "factor"), slope_text = " ", trend_color = "#CBCBCB"), class = "data.frame", row.names = c(NA, 
-1L))

dataset <- dput(dataset)
structure(list(Date = structure(c(12794, 12823, 12863, 12893, 
12921, 12948, 12978, 13003, 13048, 13073, 13108, 13137, 13172, 
13199, 13230, 13263, 13291, 13318, 13349, 13375, 13405, 13432, 
13472, 13486, 13523, 13564, 13592, 13622, 13648, 13683, 13705, 
13746, 13775, 13810, 13838, 13852, 13929, 13957, 13986, 14014, 
14053, 14067, 14110, 14139, 14166, 14196, 14224, 14266, 14294, 
14321, 14348, 14377, 14405, 14446, 14476, 14501, 14532, 14566, 
14593, 14636, 14684, 14712, 14740, 14770, 14811, 14839, 14868, 
14896, 14929, 14952, 14993, 15020, 15050, 15077, 15105, 15146, 
15174, 15208, 15238, 15265, 15293, 15315, 15350, 15385, 15412, 
15441, 15482, 15511, 15537, 15566, 15600, 15631, 15658, 15685, 
15728, 15742, 15769, 15811, 15839, 15868, 15904, 15931, 15958, 
16001, 16030, 16042, 16091, 16119, 16149, 16174, 16204, 16230, 
16268, 16302, 16330, 16359, 16386, 16412), class = "Date"), cenTF = c(FALSE, 
FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, 
FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), Value = c(0.05, 
0.06, 0.025, 0.08, 0.06, 0.07, 0.05, 0.025, 0.025, 0.1, 0.12, 
0.18, 0.14, 0.19, 0.36, 0.17, 0.09, 0.07, 0.05, 0.025, 0.05, 
0.025, 0.08, 0.05, 0.06, 0.06, 0.06, 0.05, 0.07, 0.06, 0.05, 
0.07, 0.06, 0.05, 0.05, 0.06, 0.05, 0.07, 0.1, 0.09, 0.025, 0.07, 
0.07, 0.14, 0.17, 0.11, 0.1, 0.14, 0.17, 0.17, 0.18, 0.09, 0.08, 
0.08, 0.1, 0.07, 0.07, 0.06, 0.025, 0.09, 0.07, 0.08, 0.06, 0.06, 
0.06, 0.08, 0.06, 0.06, 0.05, 0.05, 0.06, 0.06, 0.11, 0.1, 0.1, 
0.05, 0.06, 0.025, 0.06, 0.025, 0.06, 0.06, 0.07, 0.06, 0.05, 
0.07, 0.05, 0.06, 0.05, 0.05, 0.06, 0.06, 0.025, 0.05, 0.06, 
0.06, 0.06, 0.23, 0.06, 0.06, 0.06, 0.025, 0.05, 0.05, 0.1, 0.06, 
0.06, 0.06, 0.07, 0.08, 0.06, 0.07, 0.06, 0.05, 0.07, 0.06, 0.06, 
0.06)), row.names = c(NA, -118L), class = "data.frame")

plotly_1 <- function(dataset, results, 
                      cen_var="cenTF", val_var="Value", 
                      date_period =NULL  
                      ){


  dataset <- dataset %>%
   mutate(cenNM = case_when(!!ensym(cen_var) := FALSE ~ " ",
                            !!ensym(cen_var) := TRUE ~ "Value too low to detect"), 
          plotVal = !!ensym(val_var), 
          plotCen = !!ensym(cen_var), 
          pct_cens = round(sum(.data$plotCen, na.rm=TRUE)/sum(!is.na(.data$Value))*100, 1))

  #PLOTTING PARAMETERS
  legendFont <-  list(
    family = "sans-serif",
    size = 14,
    color = "#000")

  #font for axis
  axisFont <- list(
    family = "sans-serif",
    size = 17,
    color = "#000")

  #calculate trend line limits - confirm same fopr decdate as date...
  min_x <- date_period[1]
  max_x <- date_period[2]+1
  min_y <- results$slope *min_x + results$int_from_data  
  max_y <- results$slope*max_x + results$int_from_data

  #CREATE PLOT
  p <- plot_ly(dataset, x = ~Date, y = ~plotVal,
               color=I("#3182BD"),
               type='scatter',
               mode='lines', 
               showlegend=FALSE, 
               hoverinfo="none"
               ) %>%
    add_markers(data=dataset %>% filter(plotCen == FALSE),
                x = ~Date,y = ~plotVal, 
                      color=I("#3182BD"),
                symbol=I("circle"),
                size=1, 
                showlegend=FALSE, 
                hoverinfo="text", 
                text= ~paste("Value:",plotVal,"<br>Date:",Date,"<br>Censored:",plotCen)
                ) %>%
    add_markers(data=dataset %>% filter(plotCen == TRUE), 
               x = ~Date,y = ~plotVal, 
               size = 1,
               symbol = I("circle-open"),
               color=I("#3182BD"),
               showlegend=TRUE, 
               name="Value too low to detect",
               hoverinfo="text", 
               text=~paste("Value:",plotVal,"<br>Date:",Date,"<br>Censored:",plotCen)
              )

  #add trend line for significant trends only...
  if(!any(results$slope_pval > alpha,results$slope == 0)){
    p <- p %>% 
      add_segments(data=results,
                   x=min_x , xend=max_x, y=min_y , yend=max_y, 
                   color="#FCBA19",
                   name="Long-term trend", 
                   showlegend=TRUE, 
                   inherit=TRUE)
  }

  return(p)

}
tmp <- plotly_1(dataset, results, date_period = c(2005,2014))
#glimpse(tmp)

tmp

上面没有显示图例中的标记,但是 如果我注释掉 if(!any(results$slope_pval > alpha,results$slope == 0)) 语句,删失标记确实显示在图例中(如需要)

问题是,您在 plot_ly 调用中设置了 showlegend = FALSE,这对情节具有全局影响。如果您添加另一个 add_lines 而不是直接在 plot_ly 中传递线迹数据,您将获得所需的结果:

library(plotly)
library(dplyr)

# datasets
alpha <- 0.6 # not defined  in question

results <- structure(list(slope = 0, slope_p_val = 0.672652383888971, int_from_data = 0.06, 
                          pct_cens = 9.3, annual_slope_units = 0, sigclass = "No evidence of trend", 
                          sig = structure(2L, .Label = c("Significant", "Not significant"
                          ), class = "factor"), slope_text = " ", trend_color = "#CBCBCB"), class = "data.frame", row.names = c(NA, -1L))

dataset <- structure(list(Date = structure(c(12794, 12823, 12863, 12893, 
                                             12921, 12948, 12978, 13003, 13048, 13073, 13108, 13137, 13172, 
                                             13199, 13230, 13263, 13291, 13318, 13349, 13375, 13405, 13432, 
                                             13472, 13486, 13523, 13564, 13592, 13622, 13648, 13683, 13705, 
                                             13746, 13775, 13810, 13838, 13852, 13929, 13957, 13986, 14014, 
                                             14053, 14067, 14110, 14139, 14166, 14196, 14224, 14266, 14294, 
                                             14321, 14348, 14377, 14405, 14446, 14476, 14501, 14532, 14566, 
                                             14593, 14636, 14684, 14712, 14740, 14770, 14811, 14839, 14868, 
                                             14896, 14929, 14952, 14993, 15020, 15050, 15077, 15105, 15146, 
                                             15174, 15208, 15238, 15265, 15293, 15315, 15350, 15385, 15412, 
                                             15441, 15482, 15511, 15537, 15566, 15600, 15631, 15658, 15685, 
                                             15728, 15742, 15769, 15811, 15839, 15868, 15904, 15931, 15958, 
                                             16001, 16030, 16042, 16091, 16119, 16149, 16174, 16204, 16230, 
                                             16268, 16302, 16330, 16359, 16386, 16412), class = "Date"), 
                          cenTF = c(FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, 
                                    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, 
                                    FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
                                    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
                                    FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
                                    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
                                    FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
                                    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
                                    FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, 
                                    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
                                    TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
                                    TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
                                    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), 
                          Value = c(0.05,                                                                                                      0.06, 0.025, 0.08, 0.06, 0.07, 0.05, 0.025, 0.025, 0.1, 0.12, 
                                                                                                       0.18, 0.14, 0.19, 0.36, 0.17, 0.09, 0.07, 0.05, 0.025, 0.05, 
                                                                                                       0.025, 0.08, 0.05, 0.06, 0.06, 0.06, 0.05, 0.07, 0.06, 0.05, 
                                                                                                       0.07, 0.06, 0.05, 0.05, 0.06, 0.05, 0.07, 0.1, 0.09, 0.025, 0.07, 
                                                                                                       0.07, 0.14, 0.17, 0.11, 0.1, 0.14, 0.17, 0.17, 0.18, 0.09, 0.08, 
                                                                                                       0.08, 0.1, 0.07, 0.07, 0.06, 0.025, 0.09, 0.07, 0.08, 0.06, 0.06, 
                                                                                                       0.06, 0.08, 0.06, 0.06, 0.05, 0.05, 0.06, 0.06, 0.11, 0.1, 0.1, 
                                                                                                       0.05, 0.06, 0.025, 0.06, 0.025, 0.06, 0.06, 0.07, 0.06, 0.05, 
                                                                                                       0.07, 0.05, 0.06, 0.05, 0.05, 0.06, 0.06, 0.025, 0.05, 0.06, 
                                                                                                       0.06, 0.06, 0.23, 0.06, 0.06, 0.06, 0.025, 0.05, 0.05, 0.1, 0.06, 
                                                                                                       0.06, 0.06, 0.07, 0.08, 0.06, 0.07, 0.06, 0.05, 0.07, 0.06, 0.06, 
                                                                                                       0.06)), row.names = c(NA, -118L), class = "data.frame")
plotly_1 <- function(dataset,
                     results,
                     cen_var = "cenTF",
                     val_var = "Value",
                     date_period = NULL) {
  dataset <- dataset %>%
    mutate(
      cenNM = case_when(
        !!ensym(cen_var) := FALSE ~ " ",!!ensym(cen_var) := TRUE ~ "Value too low to detect"
      ),
      plotVal = !!ensym(val_var),
      plotCen = !!ensym(cen_var),
      pct_cens = round(sum(.data$plotCen, na.rm = TRUE) / sum(!is.na(.data$Value)) *
                         100, 1)
    )

  #PLOTTING PARAMETERS
  legendFont <-  list(family = "sans-serif",
                      size = 14,
                      color = "#000")

  #font for axis
  axisFont <- list(family = "sans-serif",
                   size = 17,
                   color = "#000")

  #calculate trend line limits - confirm same fopr decdate as date...
  min_x <- date_period[1]
  max_x <- date_period[2] + 1
  min_y <- results$slope * min_x + results$int_from_data
  max_y <- results$slope * max_x + results$int_from_data

  #CREATE PLOT
  p <- plot_ly(dataset,
               type = 'scatter',
               mode = 'lines',
               hoverinfo = "none") %>%
    add_lines(
      x = ~ Date,
      y = ~ plotVal,
      color = I("#3182BD"),
      showlegend = FALSE
    ) %>%
    add_markers(
      data = dataset %>% filter(plotCen == FALSE),
      x = ~ Date,
      y = ~ plotVal,
      color = I("#3182BD"),
      symbol = I("circle"),
      size = 1,
      showlegend = FALSE,
      hoverinfo = "text",
      text = ~ paste(
        "Value:",
        plotVal,
        "<br>Date:",
        Date,
        "<br>Censored:",
        plotCen
      )
    ) %>%
    add_markers(
      data = dataset %>% filter(plotCen == TRUE),
      x = ~ Date,
      y = ~ plotVal,
      size = 1,
      symbol = I("circle-open"),
      color = I("#3182BD"),
      showlegend = TRUE,
      name = "Value too low to detect",
      hoverinfo = "text",
      text =  ~ paste(
        "Value:",
        plotVal,
        "<br>Date:",
        Date,
        "<br>Censored:",
        plotCen
      )
    )

  # add trend line for significant trends only...
  if (!any(results$slope_p_val > alpha, results$slope == 0)) {
    p <- p %>%
      add_segments(
        data = results,
        x = min_x ,
        xend = max_x,
        y = min_y ,
        yend = max_y,
        color = "#FCBA19",
        name = "Long-term trend",
        showlegend = TRUE,
        inherit = TRUE
      )
  }

  return(p)

}
tmp <- plotly_1(dataset, results, date_period = c(2005, 2014))
#glimpse(tmp)

tmp

另外两条评论: 添加 alpha <- 0.6 因为它没有定义。 将 if(!any(results$slope_pval > alpha,results$slope == 0)){ 更改为 results$slope_p_val