Search code examples
rplotplotlydata-visualizationr-plotly

Understanding 3D traces in Plotly


I am using the R programming language. I made the following 3D plot in R:

# set seed for reproducibility 
#load libraries
    set.seed(123)
    library(dplyr)
    library(plotly)
    
#create data
    n <- 3
    my_grid <- expand.grid(i1 = 1:n, i2 = 1:n)
    my_grid$final_value = with(my_grid, sin(i1) + cos(i2) )
    
 
#make plot
       plot_ly() %>% 
        add_trace(data = my_grid,  x=my_grid$i1, y=my_grid$i2, z=my_grid$final_value, type='mesh3d') %>%
        add_surface(
            z = my_grid %>% as.matrix(),
            surfacecolor = my_grid,
            cauto=F,
            cmax=max(my_grid$final_value),
            cmin=min(my_grid$final_value)
        )

This produces the following plot:

enter image description here

As expected, this plot seems to be very logical : it shows a 3D surface where x = i1, y = i2, z = final_value, and the color of the plot is according "final_value".

Problem: If I try to add some more data to the grid and then create the plot:

#create more data
n <- 50
my_grid <- expand.grid(i1 = 1:n, i2 = 1:n)
my_grid$final_value = with(my_grid, sin(i1) + cos(i2) )


#make plot
plot_ly() %>% 
    add_trace(data = my_grid,  x=my_grid$i1, y=my_grid$i2, z=my_grid$final_value, type='mesh3d') %>%
    add_surface(
        z = my_grid %>% as.matrix(),
        surfacecolor = my_grid,
        cauto=F,
        cmax=max(my_grid$final_value),
        cmin=min(my_grid$final_value)
    )

enter image description here

Not only does this graph look "strange", but the "y-coordinate" (1697) within the hover text is displaying a value which is not present within the original data:

#display histogram of values

par(mfrow=c(1,3))

 hist(my_grid$i1)
 hist(my_grid$i2)
 hist(my_grid$final_value)

enter image description here

Question: In the above histogram, a value of "1697" does not appear in any of the variables. So how is it possible that such a large value is displayed within the plotly diagram?

Thanks


Solution

  • First of all you are mixing up two different trace types:

    On the one hand mesh3d and on the otherhand a surface trace. Both can handle x, y, z coordinates.

    However, you are passing a matrix as the z arguement of the surface trace (and no x and y values). Accordingly plotly is taking the values of the matrix into account for the z-axis and the dimensions of the matrix (2500 x 3) for y and x.

    Please also run schema() and navigate to:

    object ► traces ► surface ► attributes

    and

    object ► traces ► mesh3d ► attributes

    to see the differences.

    With respect to your dataset I guess you want something like this:

    # set seed for reproducibility 
    #load libraries
    set.seed(123)
    library(dplyr)
    library(plotly)
    
    #create more data
    n <- 50
    my_grid <- expand.grid(i1 = 1:n, i2 = 1:n)
    my_grid$final_value = with(my_grid, sin(i1) + cos(i2) )
    
    #make plot
    plot_ly(data = my_grid,  x=~i1, y=~i2, z=~final_value, type='mesh3d', intensity = ~final_value, colors = colorRamp(c("blue", "grey", "red")))
    

    result