plotly.R icon indicating copy to clipboard operation
plotly.R copied to clipboard

Opacity in Grouped Bar Charts with data.frame

Open roberthinch opened this issue 5 years ago • 2 comments

When plotting a grouped bar chart with variable opacity with data in a data.frame, the opacity assigned to each column is not the one specified in the data.frame. In the example below, the 2 bars in group "A" are plotted with reduced opacity, as opposed to the 2 bars with colour "C". Strangely, if the data.frame is not ordered then it plots correctly.

library( plotly )

data  = data.frame( 
  x      = c( "A", "B", "A", "B" ),
  y      = c(   1,   2,   3,   4 ),
  z      = c( "C", "C", "D", "D" ),
 opacity = c( 0.3, 0.3,   1,   1 )
)

# removing this lines the plot is correct
data = data[ order( data$x ),]

p = plot_ly( 
  data   = data, 
  x      = ~x, 
  y      = ~y, 
  color  = ~z, 
  marker = list( opacity = ~opacity ),
  type   = "bar" ) %>% 
layout( barmode = "group" )
show( p )


roberthinch avatar Dec 02 '19 10:12 roberthinch

Likely related to https://github.com/ropensci/plotly/issues/1657

cpsievert avatar Feb 05 '20 22:02 cpsievert

I have a similar problem that might be caused by the same bug, but it manifests itself differently. When I make a 3D scatterplot and use opacity as an attribute, it maps it to the wrong points (or ‘layer’ of points) in the plot. In this case, I want the middle ‘layer’ of points to have 100% opacity. If I assign an opacity of 1 to the middle layer, the bottom layer is opaque and the middle layer is translucent (dataframe test.opac.ideal). When I assign an opacity of 1 to the bottom layer, I get the plot I want with an opaque middle layer (dataframe test.opac.bug). When I read the above post, I tried randomizing the order of this test dataset (dataframe test.opac.ideal.reordered), but in that case all points are opaque regardless of the ‘opac’ column.

test.data <- tibble(low = rep(1, 5),
                     mid = rep(2, 5),
                     high = rep(3, 5),
                     x = seq(1:5),
                     y = seq(1:5)) %>% 
  tidyr::expand(low,mid,high, x, y) %>% 
  tidyr::gather("layer", "value", low:high) 

test.opac.ideal <- test.data %>%
  mutate(opac = ifelse(layer == "mid", 1, 0.3))

test.opac.bug <- test.data %>%
  mutate(opac = ifelse(layer == "high", 1, 0.3))

plot_ly(data = test.opac.ideal, x = ~x, y = ~y, z = ~value, 
        split = ~layer,
        type = "scatter3d", mode = "markers", color = 2, opacity = ~opac,
        scene = "scene1") %>% 
  layout(scene1 = list(camera = list(eye = list(x = 2, y = -2, z = 1.6)),
                  aspectratio = list( x = 1, y = 1)))

plot_ly(data = test.opac.bug, x = ~x, y = ~y, z = ~value, 
        split = ~layer,
        type = "scatter3d", mode = "markers", color = 2, opacity = ~opac,
        scene = "scene1") %>% 
  layout(scene1 = list(camera = list(eye = list(x = 2, y = -2, z = 1.6)),
                  aspectratio = list( x = 1, y = 1)))

test.opac.ideal.reordered <- test.opac.ideal[sample(1:nrow(test.opac.ideal)), ] 

plot_ly(data = test.opac.ideal.reordered, x = ~x, y = ~y, z = ~value, 
        split = ~layer,
        type = "scatter3d", mode = "markers", color = 2, opacity = ~opac,
        scene = "scene1") %>% 
  layout(scene1 = list(camera = list(eye = list(x = 2, y = -2, z = 1.6)),
                       aspectratio = list( x = 1, y = 1)))

ergulsonc avatar Apr 11 '22 21:04 ergulsonc