5 min read

Plotting a regression surface (3D)

Load packages

library(tidyverse)
library(plotly)

Data

Some sample data

data(tips, package= "reshape2")

Regression model

lm1 <- lm(tip ~ total_bill + size, data = tips)
lm1_coef <- coef(lm1)

Sequence

x1_seq <- seq(min(tips$total_bill), max(tips$total_bill), length.out = 25)
x2_seq <- seq(min(tips$size), max(tips$size), length.out = 6)

Compute grid

z2 <- t(outer(x1_seq, x2_seq, 
              function(x,y) lm1_coef[1]+lm1_coef[2]*x+lm1_coef[3]*y))
z2
#>          [,1]     [,2]     [,3]     [,4]     [,5]     [,6]     [,7]     [,8]
#> [1,] 1.146172 1.330595 1.515017 1.699439 1.883862 2.068284 2.252706 2.437128
#> [2,] 1.338770 1.523193 1.707615 1.892037 2.076459 2.260882 2.445304 2.629726
#> [3,] 1.531368 1.715790 1.900213 2.084635 2.269057 2.453479 2.637902 2.822324
#> [4,] 1.723966 1.908388 2.092810 2.277233 2.461655 2.646077 2.830500 3.014922
#> [5,] 1.916564 2.100986 2.285408 2.469830 2.654253 2.838675 3.023097 3.207520
#> [6,] 2.109161 2.293584 2.478006 2.662428 2.846851 3.031273 3.215695 3.400117
#>          [,9]    [,10]    [,11]    [,12]    [,13]    [,14]    [,15]    [,16]
#> [1,] 2.621551 2.805973 2.990395 3.174818 3.359240 3.543662 3.728084 3.912507
#> [2,] 2.814149 2.998571 3.182993 3.367415 3.551838 3.736260 3.920682 4.105104
#> [3,] 3.006746 3.191169 3.375591 3.560013 3.744435 3.928858 4.113280 4.297702
#> [4,] 3.199344 3.383766 3.568189 3.752611 3.937033 4.121455 4.305878 4.490300
#> [5,] 3.391942 3.576364 3.760786 3.945209 4.129631 4.314053 4.498476 4.682898
#> [6,] 3.584540 3.768962 3.953384 4.137807 4.322229 4.506651 4.691073 4.875496
#>         [,17]    [,18]    [,19]    [,20]    [,21]    [,22]    [,23]    [,24]
#> [1,] 4.096929 4.281351 4.465774 4.650196 4.834618 5.019040 5.203463 5.387885
#> [2,] 4.289527 4.473949 4.658371 4.842794 5.027216 5.211638 5.396060 5.580483
#> [3,] 4.482125 4.666547 4.850969 5.035391 5.219814 5.404236 5.588658 5.773080
#> [4,] 4.674722 4.859145 5.043567 5.227989 5.412411 5.596834 5.781256 5.965678
#> [5,] 4.867320 5.051742 5.236165 5.420587 5.605009 5.789432 5.973854 6.158276
#> [6,] 5.059918 5.244340 5.428762 5.613185 5.797607 5.982029 6.166452 6.350874
#>         [,25]
#> [1,] 5.572307
#> [2,] 5.764905
#> [3,] 5.957503
#> [4,] 6.150101
#> [5,] 6.342698
#> [6,] 6.535296

Draw the plane with “plot_ly” and add points with “add_trace”

plot_ly(x=~x1_seq, y=~x2_seq, z=~z2,type="surface") %>%
  add_trace(data=tips, 
            x=~total_bill, y=~size, z=~tip, 
            mode="markers", 
            type="scatter3d",
            marker = list(color="#00998a", 
                          opacity=0.7, 
                          symbol=105)) %>%
  layout(scene = list(
    aspectmode = "manual", 
    aspectratio = list(x=1, y=1, z=1),
    xaxis = list(title = "total_bill"),
    yaxis = list(title = "size"),
    zaxis = list(title = "tip")))

Reproducibility

#> ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────
#>  setting  value                       
#>  version  R version 4.0.2 (2020-06-22)
#>  os       macOS Catalina 10.15.7      
#>  system   x86_64, darwin17.0          
#>  ui       X11                         
#>  language (EN)                        
#>  collate  en_US.UTF-8                 
#>  ctype    en_US.UTF-8                 
#>  tz       Europe/Berlin               
#>  date     2020-12-08                  
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────
#>  package     * version date       lib source        
#>  assertthat    0.2.1   2019-03-21 [1] CRAN (R 4.0.0)
#>  backports     1.2.0   2020-11-02 [1] CRAN (R 4.0.2)
#>  blogdown      0.21    2020-10-11 [1] CRAN (R 4.0.2)
#>  bookdown      0.21    2020-10-13 [1] CRAN (R 4.0.2)
#>  broom         0.7.2   2020-10-20 [1] CRAN (R 4.0.2)
#>  callr         3.5.1   2020-10-13 [1] CRAN (R 4.0.2)
#>  cellranger    1.1.0   2016-07-27 [1] CRAN (R 4.0.0)
#>  cli           2.2.0   2020-11-20 [1] CRAN (R 4.0.2)
#>  codetools     0.2-16  2018-12-24 [2] CRAN (R 4.0.2)
#>  colorspace    2.0-0   2020-11-11 [1] CRAN (R 4.0.2)
#>  crayon        1.3.4   2017-09-16 [1] CRAN (R 4.0.0)
#>  crosstalk     1.1.0.1 2020-03-13 [1] CRAN (R 4.0.0)
#>  data.table    1.13.2  2020-10-19 [1] CRAN (R 4.0.2)
#>  DBI           1.1.0   2019-12-15 [1] CRAN (R 4.0.0)
#>  dbplyr        2.0.0   2020-11-03 [1] CRAN (R 4.0.2)
#>  desc          1.2.0   2018-05-01 [1] CRAN (R 4.0.0)
#>  devtools      2.3.2   2020-09-18 [1] CRAN (R 4.0.2)
#>  digest        0.6.27  2020-10-24 [1] CRAN (R 4.0.2)
#>  dplyr       * 1.0.2   2020-08-18 [1] CRAN (R 4.0.2)
#>  ellipsis      0.3.1   2020-05-15 [1] CRAN (R 4.0.0)
#>  evaluate      0.14    2019-05-28 [1] CRAN (R 4.0.0)
#>  fansi         0.4.1   2020-01-08 [1] CRAN (R 4.0.0)
#>  farver        2.0.3   2020-01-16 [1] CRAN (R 4.0.0)
#>  forcats     * 0.5.0   2020-03-01 [1] CRAN (R 4.0.0)
#>  fs            1.5.0   2020-07-31 [1] CRAN (R 4.0.2)
#>  generics      0.1.0   2020-10-31 [1] CRAN (R 4.0.2)
#>  ggplot2     * 3.3.2   2020-06-19 [1] CRAN (R 4.0.0)
#>  glue          1.4.2   2020-08-27 [1] CRAN (R 4.0.2)
#>  gtable        0.3.0   2019-03-25 [1] CRAN (R 4.0.0)
#>  haven         2.3.1   2020-06-01 [1] CRAN (R 4.0.0)
#>  hms           0.5.3   2020-01-08 [1] CRAN (R 4.0.0)
#>  htmltools     0.5.0   2020-06-16 [1] CRAN (R 4.0.0)
#>  htmlwidgets   1.5.2   2020-10-03 [1] CRAN (R 4.0.2)
#>  httr          1.4.2   2020-07-20 [1] CRAN (R 4.0.2)
#>  jsonlite      1.7.1   2020-09-07 [1] CRAN (R 4.0.2)
#>  knitr         1.30    2020-09-22 [1] CRAN (R 4.0.2)
#>  lazyeval      0.2.2   2019-03-15 [1] CRAN (R 4.0.0)
#>  lifecycle     0.2.0   2020-03-06 [1] CRAN (R 4.0.0)
#>  lubridate     1.7.9.2 2020-11-13 [1] CRAN (R 4.0.2)
#>  magrittr      2.0.1   2020-11-17 [1] CRAN (R 4.0.2)
#>  memoise       1.1.0   2017-04-21 [1] CRAN (R 4.0.0)
#>  modelr        0.1.8   2020-05-19 [1] CRAN (R 4.0.0)
#>  munsell       0.5.0   2018-06-12 [1] CRAN (R 4.0.0)
#>  pillar        1.4.7   2020-11-20 [1] CRAN (R 4.0.2)
#>  pkgbuild      1.1.0   2020-07-13 [1] CRAN (R 4.0.2)
#>  pkgconfig     2.0.3   2019-09-22 [1] CRAN (R 4.0.0)
#>  pkgload       1.1.0   2020-05-29 [1] CRAN (R 4.0.0)
#>  plotly      * 4.9.2.1 2020-04-04 [1] CRAN (R 4.0.0)
#>  prettyunits   1.1.1   2020-01-24 [1] CRAN (R 4.0.0)
#>  processx      3.4.5   2020-11-30 [1] CRAN (R 4.0.2)
#>  ps            1.4.0   2020-10-07 [1] CRAN (R 4.0.2)
#>  purrr       * 0.3.4   2020-04-17 [1] CRAN (R 4.0.0)
#>  R6            2.5.0   2020-10-28 [1] CRAN (R 4.0.2)
#>  Rcpp          1.0.5   2020-07-06 [1] CRAN (R 4.0.2)
#>  readr       * 1.4.0   2020-10-05 [1] CRAN (R 4.0.2)
#>  readxl        1.3.1   2019-03-13 [1] CRAN (R 4.0.0)
#>  remotes       2.2.0   2020-07-21 [1] CRAN (R 4.0.2)
#>  reprex        0.3.0   2019-05-16 [1] CRAN (R 4.0.0)
#>  rlang         0.4.9   2020-11-26 [1] CRAN (R 4.0.2)
#>  rmarkdown     2.5     2020-10-21 [1] CRAN (R 4.0.2)
#>  rprojroot     2.0.2   2020-11-15 [1] CRAN (R 4.0.2)
#>  rstudioapi    0.13    2020-11-12 [1] CRAN (R 4.0.2)
#>  rvest         0.3.6   2020-07-25 [1] CRAN (R 4.0.2)
#>  scales        1.1.1   2020-05-11 [1] CRAN (R 4.0.0)
#>  sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 4.0.0)
#>  stringi       1.5.3   2020-09-09 [1] CRAN (R 4.0.2)
#>  stringr     * 1.4.0   2019-02-10 [1] CRAN (R 4.0.0)
#>  testthat      3.0.0   2020-10-31 [1] CRAN (R 4.0.2)
#>  tibble      * 3.0.4   2020-10-12 [1] CRAN (R 4.0.2)
#>  tidyr       * 1.1.2   2020-08-27 [1] CRAN (R 4.0.2)
#>  tidyselect    1.1.0   2020-05-11 [1] CRAN (R 4.0.0)
#>  tidyverse   * 1.3.0   2019-11-21 [1] CRAN (R 4.0.0)
#>  usethis       1.6.3   2020-09-17 [1] CRAN (R 4.0.2)
#>  vctrs         0.3.5   2020-11-17 [1] CRAN (R 4.0.2)
#>  viridisLite   0.3.0   2018-02-01 [1] CRAN (R 4.0.0)
#>  withr         2.3.0   2020-09-22 [1] CRAN (R 4.0.2)
#>  xfun          0.19    2020-10-30 [1] CRAN (R 4.0.2)
#>  xml2          1.3.2   2020-04-23 [1] CRAN (R 4.0.0)
#>  yaml          2.2.1   2020-02-01 [1] CRAN (R 4.0.0)
#> 
#> [1] /Users/sebastiansaueruser/Rlibs
#> [2] /Library/Frameworks/R.framework/Versions/4.0/Resources/library