plotly / plotly/plotly.R

Unexpected attribute mapping with missing values in x/y

Open
#1,815 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
R
Stars
2.7k
Forks
641
PR merge metrics
No merged PRs in 30d

Description

Dear devs,

it seems like NA values in x/y values (i.e. mapped to coordinates) cause issues (or unexpected behavior) with mapping of other attributes, in this case opacity. I assume this is in-line with #1126.
The attribute seems to be recycled across groups, or only mapped to a single group, depending on how the argument was supplied (referenced as higher and lower level mapping in code).
I was able to reproduce the problem with the code below. Note, that the attribute vector is generated as a column of the data.frame used for plotting.

Cheers!

library(plotly)

n <- 100

# generate test data set with grouping factor z for color
# and index (used for customdata in event_data())
# in shiny
testdat <- data.frame(x = seq_len(n),
                      y = rnorm(n),
                      yy = rnorm(n),
                      z = gl(5, 20),
                      .index = seq_len(n))

# generate attribute vector for opacity
# based on .index (active selection in shiny)
testdat$.opacity <- ifelse(testdat$.index %in% 5:14, 0.9, 0.1)

# assign missing values
testdat$yy[15:19] <- NA

# mapping vector
colvector <- c('1' = "black",
               '2' = "red",
               '3' = "darkorange",
               '4' = "steelblue",
               '5' = "seagreen4")

# "lower level" mapping ---------------------------------------------------

# works as expected
plot_ly(data = testdat) %>% 
    add_markers(type = "scatter",
                x = ~x,
                y = ~y,
                color = ~as.factor(z),
                colors = colvector,
                customdata = ~.index,
                marker = list(opacity = ~.opacity))

# when missing values are present on y-value
# seems to recycle attributes after first group
plot_ly(data = testdat) %>% 
    add_markers(type = "scatter",
                x = ~x,
                y = ~yy,
                color = ~as.factor(z),
                colors = colvector,
                customdata = ~.index,
                marker = list(opacity = ~.opacity))



# "higher level" mapping --------------------------------------------------



# when attribute is mapped at "higher level"
# first "z group" is given opacity attribute,
# but not others
plot_ly(data = testdat) %>% 
    add_markers(type = "scatter",
                x = ~x,
                y = ~y,
                color = ~as.factor(z),
                colors = colvector,
                customdata = ~.index,
                opacity =  ~.opacity)

# when attribute is mapped at "higher level"
# and missing values present,
# opacity not mapped at all
plot_ly(data = testdat) %>% 
    add_markers(type = "scatter",
                x = ~x,
                y = ~yy,
                color = ~as.factor(z),
                colors = colvector,
                customdata = ~.index,
                opacity = ~.opacity)


Session Info:

> sessionInfo()
R version 3.6.3 (2020-02-29)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18363)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                           LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] plotly_4.9.2       ggplot2_3.3.0.9000

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4.6      pillar_1.4.4      compiler_3.6.3    later_1.0.0       tools_3.6.3       digest_0.6.25     jsonlite_1.6.1   
 [8] lifecycle_0.2.0   tibble_3.0.1      gtable_0.3.0      viridisLite_0.3.0 pkgconfig_2.0.3   rlang_0.4.6       shiny_1.4.0      
[15] rstudioapi_0.11   crosstalk_1.0.0   yaml_2.2.1        fastmap_1.0.1     withr_2.2.0       dplyr_0.8.5       httr_1.4.1       
[22] vctrs_0.2.4       htmlwidgets_1.5.1 grid_3.6.3        tidyselect_1.0.0  glue_1.4.0        data.table_1.12.8 R6_2.4.1         
[29] farver_2.0.3      purrr_0.3.4       tidyr_1.0.2       magrittr_1.5      scales_1.1.0      promises_1.1.0    ellipsis_0.3.0   
[36] htmltools_0.4.0   assertthat_0.2.1  xtable_1.8-4      mime_0.9          colorspace_1.4-1  httpuv_1.5.2      lazyeval_0.2.2   
[43] munsell_0.5.0     crayon_1.3.4     

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the supplied R reproduction with plotly.R, comparing the cases using y and yy and the lower-level and higher-level opacity mappings. Trace how missing y values and grouped traces affect attribute vectors, then verify that opacity remains aligned with the corresponding observations and groups.

Written by the indexing model from the issue text.

Assessment

Tech stack
r
Domain
data-visualization
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.