Search code examples
r3dplotlydata-visualization

Adding Contour Lines to 3D Plots


I am working with the R programming language. I made the following 3 Dimensional Plot using the "plotly" library:

library(dplyr)
library(plotly)

  my_function <- function(x,y) {
    
    final_value = (1 - x)^2 + 100*((y - x^2)^2)
     
    }

input_1 <- seq(-1.5, 1.5,0.1)
input_2 <- seq(-1.5, 1.5,0.1)

z <- outer(input_1, input_2, my_function)

plot_ly(x = input_1, y = input_2, z = z) %>% add_surface()

enter image description here

I am now trying to add "contour lines" to the above plot as shown below: https://plotly.com/r/3d-surface-plots/

enter image description here

I am trying to adapt the code from the "plotly website" to make these contours, but I am not sure how to do this:

Graph 1:

# This might have worked?
fig <- plot_ly(z = ~z) %>% add_surface(
  contours = list(
    z = list(
      show=TRUE,
      usecolormap=TRUE,
      highlightcolor="#ff0000",
      project=list(z=TRUE)
      )
    )
  )
fig <- fig %>% layout(
    scene = list(
      camera=list(
        eye = list(x=1.87, y=0.88, z=-0.64)
        )
      )
  )

enter image description here

Graph 2:

# I don't think this worked?
fig <- plot_ly(
  type = 'surface',
  contours = list(
    x = list(show = TRUE, start = 1.5, end = 2, size = 0.04, color = 'white'),
    z = list(show = TRUE, start = 0.5, end = 0.8, size = 0.05)),
  x = ~x,
  y = ~y,
  z = ~z)
fig <- fig %>% layout(
    scene = list(
      xaxis = list(nticks = 20),
      zaxis = list(nticks = 4),
      camera = list(eye = list(x = 0, y = -1, z = 0.5)),
      aspectratio = list(x = .9, y = .8, z = 0.2)))

fig

enter image description here

Can someone please show me how to correctly adapt these above codes?


Solution

  • The contour lines are on your plots, but may not be super visible due to the parameters in the contours.z list. Here's how you can tweak the contour lines to fit your needs:

    fig <- plot_ly(z = ~z) %>% add_surface(
      contours = list(
        z = list(
          show = TRUE,
          # project=list(z=TRUE)       # (don't) project contour lines to underlying plane
          # usecolormap = TRUE,        # (don't) use surface color scale for contours
          color = "white",             # set contour color
          width = 1,                   # set contour thickness
          highlightcolor = "#ff0000",  # highlight contour on hover
          start = 0,                   # include contours from z = 0...
          end = 1400,                  # to z = 1400...
          size = 100                   # every 100 units
    
        )
      )
    )
    

    You can draw lines along the other dimensions by passing lists to x or y. (Per follow-up question from OP) you can change the surface color scale using colorscale, either specifying one of the named colorscale options or building your own. Example:

    fig <- plot_ly(z = ~z) %>% add_surface(
      colorscale = "Picnic",
      contours = list(
        x = list(show=TRUE, color="#a090b0", width=2, start=0, end=30, size=7.5),
        y = list(show=TRUE, color="#a090b0", width=2, start=0, end=30, size=7.5),
        z = list(show=TRUE, color="#a090b0", width=2, start=0, end=1400, size=300)
      )
    )