User Guide: 3 Debugging ggplots

‘ggpmisc’ 0.2.17

Pedro J. Aphalo

2018-05-04

Preliminaries

library(ggplot2)
library(ggpmisc)
library(tibble)

We generate some artificial data.

set.seed(4321)
# generate artificial data
x <- 1:100
y <- (x + x^2 + x^3) + rnorm(length(x), mean = 0, sd = mean(x^3) / 4)
my.data <- data.frame(x, 
                      y, 
                      group = c("A", "B"), 
                      y2 = y * c(0.5, 2),
                      block = c("a", "a", "b", "b"))

We change the default theme to an uncluttered one.

old_theme <- theme_set(theme_bw())

Introduction

The motivation for writing these stats and geoms is that at the moment it is in many cases not possible to set breakpoints inside the code of stats and geoms. This can make it tedious to see how these functions work, as one may need to add print statements to their source code to achieve this. I wrote these functions as tools to help in the development of this package itself, and as a way of learning myself how data are passed around within the different components of a ggplot object when it is printed.

The stats described in this vignette are very simple and print a summary of their data input to the console. In addition they also return a data frame containing labels suitable for plotting with geom “text” or geom “label”. However, starting from version 0.2.7 of the package the default geom is “null”. The values are listed to the console at the time when the ggplot object is printed.

As shown here, no other geom or stat is required, however in the remaining examples we include geom_point() to make the data on the plot visible.

ggplot(my.data, aes(x, y)) + stat_debug_group()
## [1] "Input 'data' to 'compute_group()':"
## # A tibble: 100 x 4
##        x        y PANEL group
##  * <dbl>    <dbl> <fct> <int>
##  1     1  -27205. 1        -1
##  2     2  -14243. 1        -1
##  3     3   45791. 1        -1
##  4     4   53731. 1        -1
##  5     5   -8029. 1        -1
##  6     6  102864. 1        -1
##  7     7  -18547. 1        -1
##  8     8   13081. 1        -1
##  9     9   79924. 1        -1
## 10    10  -44711. 1        -1
## # ... with 90 more rows

In the absence of facets or groups we get just get the summary from one data frame.

ggplot(my.data, aes(x, y)) + geom_point() + stat_debug_group()
## [1] "Input 'data' to 'compute_group()':"
## # A tibble: 100 x 4
##        x        y PANEL group
##  * <dbl>    <dbl> <fct> <int>
##  1     1  -27205. 1        -1
##  2     2  -14243. 1        -1
##  3     3   45791. 1        -1
##  4     4   53731. 1        -1
##  5     5   -8029. 1        -1
##  6     6  102864. 1        -1
##  7     7  -18547. 1        -1
##  8     8   13081. 1        -1
##  9     9   79924. 1        -1
## 10    10  -44711. 1        -1
## # ... with 90 more rows

ggplot(my.data, aes(x, y)) + geom_point() + stat_debug_panel()
## [1] "Input 'data' to 'compute_panel()':"
## # A tibble: 100 x 4
##        x        y PANEL group
##    <dbl>    <dbl> <fct> <int>
##  1     1  -27205. 1        -1
##  2     2  -14243. 1        -1
##  3     3   45791. 1        -1
##  4     4   53731. 1        -1
##  5     5   -8029. 1        -1
##  6     6  102864. 1        -1
##  7     7  -18547. 1        -1
##  8     8   13081. 1        -1
##  9     9   79924. 1        -1
## 10    10  -44711. 1        -1
## # ... with 90 more rows

In the case of grouping then one data frame is summarized for each group in the ggplot object.

ggplot(my.data, aes(x, y, colour = group)) + geom_point() + 
  stat_debug_group()
## [1] "Input 'data' to 'compute_group()':"
## # A tibble: 50 x 5
##        x       y colour PANEL group
##  * <dbl>   <dbl> <fct>  <fct> <int>
##  1     1 -27205. A      1         1
##  2     3  45791. A      1         1
##  3     5  -8029. A      1         1
##  4     7 -18547. A      1         1
##  5     9  79924. A      1         1
##  6    11  -2824. A      1         1
##  7    13 -78017. A      1         1
##  8    15 -74281. A      1         1
##  9    17   9904. A      1         1
## 10    19 -94023. A      1         1
## # ... with 40 more rows
## [1] "Input 'data' to 'compute_group()':"
## # A tibble: 50 x 5
##        x        y colour PANEL group
##  * <dbl>    <dbl> <fct>  <fct> <int>
##  1     2  -14243. B      1         2
##  2     4   53731. B      1         2
##  3     6  102864. B      1         2
##  4     8   13081. B      1         2
##  5    10  -44711. B      1         2
##  6    12   23840. B      1         2
##  7    14   75602. B      1         2
##  8    16  104677. B      1         2
##  9    18  -68747. B      1         2
## 10    20  -39230. B      1         2
## # ... with 40 more rows

Without facets, we still have only one panel.

ggplot(my.data, aes(x, y, colour = group)) + geom_point() + 
  stat_debug_panel()
## [1] "Input 'data' to 'compute_panel()':"
## # A tibble: 100 x 5
##        x        y colour PANEL group
##    <dbl>    <dbl> <fct>  <fct> <int>
##  1     1  -27205. A      1         1
##  2     2  -14243. B      1         2
##  3     3   45791. A      1         1
##  4     4   53731. B      1         2
##  5     5   -8029. A      1         1
##  6     6  102864. B      1         2
##  7     7  -18547. A      1         1
##  8     8   13081. B      1         2
##  9     9   79924. A      1         1
## 10    10  -44711. B      1         2
## # ... with 90 more rows

The data are similar, except for the column named after the aesthetic, for the aesthetics used for grouping.

ggplot(my.data, aes(x, y, shape = group)) + geom_point() + 
  stat_debug_group()
## [1] "Input 'data' to 'compute_group()':"
## # A tibble: 50 x 5
##        x       y shape PANEL group
##  * <dbl>   <dbl> <fct> <fct> <int>
##  1     1 -27205. A     1         1
##  2     3  45791. A     1         1
##  3     5  -8029. A     1         1
##  4     7 -18547. A     1         1
##  5     9  79924. A     1         1
##  6    11  -2824. A     1         1
##  7    13 -78017. A     1         1
##  8    15 -74281. A     1         1
##  9    17   9904. A     1         1
## 10    19 -94023. A     1         1
## # ... with 40 more rows
## [1] "Input 'data' to 'compute_group()':"
## # A tibble: 50 x 5
##        x        y shape PANEL group
##  * <dbl>    <dbl> <fct> <fct> <int>
##  1     2  -14243. B     1         2
##  2     4   53731. B     1         2
##  3     6  102864. B     1         2
##  4     8   13081. B     1         2
##  5    10  -44711. B     1         2
##  6    12   23840. B     1         2
##  7    14   75602. B     1         2
##  8    16  104677. B     1         2
##  9    18  -68747. B     1         2
## 10    20  -39230. B     1         2
## # ... with 40 more rows

If we use as geom "label" or "text" a debug summary is added to the plot itself, we can use other arguments valid for the geom used, in this case vjust.

ggplot(my.data, aes(x, y, shape = group)) + geom_point() + 
  stat_debug_group(geom = "label", vjust = c(-0.5,1.5))
## [1] "Input 'data' to 'compute_group()':"
## # A tibble: 50 x 5
##        x       y shape PANEL group
##  * <dbl>   <dbl> <fct> <fct> <int>
##  1     1 -27205. A     1         1
##  2     3  45791. A     1         1
##  3     5  -8029. A     1         1
##  4     7 -18547. A     1         1
##  5     9  79924. A     1         1
##  6    11  -2824. A     1         1
##  7    13 -78017. A     1         1
##  8    15 -74281. A     1         1
##  9    17   9904. A     1         1
## 10    19 -94023. A     1         1
## # ... with 40 more rows
## [1] "Input 'data' to 'compute_group()':"
## # A tibble: 50 x 5
##        x        y shape PANEL group
##  * <dbl>    <dbl> <fct> <fct> <int>
##  1     2  -14243. B     1         2
##  2     4   53731. B     1         2
##  3     6  102864. B     1         2
##  4     8   13081. B     1         2
##  5    10  -44711. B     1         2
##  6    12   23840. B     1         2
##  7    14   75602. B     1         2
##  8    16  104677. B     1         2
##  9    18  -68747. B     1         2
## 10    20  -39230. B     1         2
## # ... with 40 more rows

The summary function can be a user defined one, which allows lots of flexibility.

ggplot(my.data, aes(x, y)) + geom_point() + 
  stat_debug_group(summary.fun = summary)
## [1] "Input 'data' to 'compute_group()':"
##        x                y           PANEL       group   
##  Min.   :  1.00   Min.   : -94023   1:100   Min.   :-1  
##  1st Qu.: 25.75   1st Qu.:  40345           1st Qu.:-1  
##  Median : 50.50   Median : 154036           Median :-1  
##  Mean   : 50.50   Mean   : 266433           Mean   :-1  
##  3rd Qu.: 75.25   3rd Qu.: 422069           3rd Qu.:-1  
##  Max.   :100.00   Max.   :1077469           Max.   :-1

ggplot(my.data, aes(x, y)) + geom_point() + 
  stat_debug_group(summary.fun = head)
## [1] "Input 'data' to 'compute_group()':"
##   x          y PANEL group
## 1 1 -27205.450     1    -1
## 2 2 -14242.651     1    -1
## 3 3  45790.918     1    -1
## 4 4  53731.420     1    -1
## 5 5  -8028.578     1    -1
## 6 6 102863.943     1    -1

ggplot(my.data, aes(x, y)) + geom_point() + 
  stat_debug_group(summary.fun = nrow)
## [1] "Input 'data' to 'compute_group()':"
## [1] 100

The default.

ggplot(my.data, aes(x, y)) + geom_point() + 
  stat_debug_group(summary.fun = as_tibble)
## [1] "Input 'data' to 'compute_group()':"
## # A tibble: 100 x 4
##        x        y PANEL group
##  * <dbl>    <dbl> <fct> <int>
##  1     1  -27205. 1        -1
##  2     2  -14243. 1        -1
##  3     3   45791. 1        -1
##  4     4   53731. 1        -1
##  5     5   -8029. 1        -1
##  6     6  102864. 1        -1
##  7     7  -18547. 1        -1
##  8     8   13081. 1        -1
##  9     9   79924. 1        -1
## 10    10  -44711. 1        -1
## # ... with 90 more rows

ggplot(my.data, aes(x, y)) + geom_point() + 
  stat_debug_group(summary.fun = head, summary.fun.args = list(n = 3))
## [1] "Input 'data' to 'compute_group()':"
##   x         y PANEL group
## 1 1 -27205.45     1    -1
## 2 2 -14242.65     1    -1
## 3 3  45790.92     1    -1

This next chunk showing how to print the whole data frame is not run as its output is more than 100 lines long as the data set contains 100 observations.

ggplot(my.data, aes(x, y)) + geom_point() + 
  stat_debug_group(summary.fun = function(x) {x})

With grouping, for each group the compute_group() function is called with a subset of the data.

ggplot(my.data, aes(x, y, colour = group)) + geom_point() + 
  stat_debug_group(summary.fun = head, summary.fun.args = list(n = 3))
## [1] "Input 'data' to 'compute_group()':"
##   x          y colour PANEL group
## 1 1 -27205.450      A     1     1
## 3 3  45790.918      A     1     1
## 5 5  -8028.578      A     1     1
## [1] "Input 'data' to 'compute_group()':"
##   x         y colour PANEL group
## 2 2 -14242.65      B     1     2
## 4 4  53731.42      B     1     2
## 6 6 102863.94      B     1     2

In this example with grouping and facets, within each panel the compute_group() function is called for each group, in total four times.

ggplot(my.data, aes(x, y, colour = group)) + geom_point() + 
  stat_debug_group(summary.fun = nrow) +
  facet_wrap(~block)
## [1] "Input 'data' to 'compute_group()':"
## [1] 25
## [1] "Input 'data' to 'compute_group()':"
## [1] 25
## [1] "Input 'data' to 'compute_group()':"
## [1] 25
## [1] "Input 'data' to 'compute_group()':"
## [1] 25

With facets, for each panel the compute_panel() function is called with a subset of the data that is not split by groups. For our example, it is called twice.

ggplot(my.data, aes(x, y, colour = group)) + geom_point() + 
  stat_debug_panel(summary.fun = nrow) +
  facet_wrap(~block)
## [1] "Input 'data' to 'compute_panel()':"
## [1] 50
## [1] "Input 'data' to 'compute_panel()':"
## [1] 50

Finally we show how geom_debug() can be used. First to print to the console the data as passed to geoms.

ggplot(my.data, aes(x, y, colour = group)) + geom_point() + 
  geom_debug(summary.fun = head)
##    colour x          y PANEL group
## 1 #F8766D 1 -27205.450     1     1
## 2 #00BFC4 2 -14242.651     1     2
## 3 #F8766D 3  45790.918     1     1
## 4 #00BFC4 4  53731.420     1     2
## 5 #F8766D 5  -8028.578     1     1
## 6 #00BFC4 6 102863.943     1     2

We may even save the data input of the geom to a variable in the global environment, but this takes place at the time the ggplot object is printed.

tidy.assign <- function(value, name, pos = .GlobalEnv, ...) {
  assign(x = name, value = value, inherits = FALSE, pos = pos, ...)
}
ggplot(my.data, aes(x, y, colour = group)) + 
  geom_point() + 
  geom_debug(summary.fun = tidy.assign, 
             summary.fun.args = list(name = "debug_data"),
             print.fun = NULL)
debug_data
##      colour   x             y PANEL group
## 1   #F8766D   1  -27205.45039     1     1
## 2   #00BFC4   2  -14242.65108     1     2
## 3   #F8766D   3   45790.91787     1     1
## 4   #00BFC4   4   53731.42037     1     2
## 5   #F8766D   5   -8028.57848     1     1
## 6   #00BFC4   6  102863.94292     1     2
## 7   #F8766D   7  -18547.28227     1     1
## 8   #00BFC4   8   13080.52133     1     2
## 9   #F8766D   9   79924.32504     1     1
## 10  #00BFC4  10  -44711.49916     1     2
## 11  #F8766D  11   -2823.73559     1     1
## 12  #00BFC4  12   23839.55471     1     2
## 13  #F8766D  13  -78016.69001     1     1
## 14  #00BFC4  14   75601.95706     1     2
## 15  #F8766D  15  -74281.23373     1     1
## 16  #00BFC4  16  104676.72111     1     2
## 17  #F8766D  17    9903.67373     1     1
## 18  #00BFC4  18  -68746.93124     1     2
## 19  #F8766D  19  -94022.62267     1     1
## 20  #00BFC4  20  -39230.19259     1     2
## 21  #F8766D  21   40550.54085     1     1
## 22  #00BFC4  22   10961.10296     1     2
## 23  #F8766D  23   12149.63105     1     1
## 24  #00BFC4  24   52254.25671     1     2
## 25  #F8766D  25    9950.24731     1     1
## 26  #00BFC4  26    3101.82898     1     2
## 27  #F8766D  27   23485.44314     1     1
## 28  #00BFC4  28   41668.54023     1     2
## 29  #F8766D  29  -27901.59355     1     1
## 30  #00BFC4  30  -59669.17456     1     2
## 31  #F8766D  31   39726.66001     1     1
## 32  #00BFC4  32   76038.66842     1     2
## 33  #F8766D  33  109169.84766     1     1
## 34  #00BFC4  34   10202.63915     1     2
## 35  #F8766D  35   98481.72725     1     1
## 36  #00BFC4  36      73.97657     1     2
## 37  #F8766D  37   40859.18209     1     1
## 38  #00BFC4  38  104296.43202     1     2
## 39  #F8766D  39   76002.67764     1     1
## 40  #00BFC4  40  146450.81373     1     2
## 41  #F8766D  41   61283.85767     1     1
## 42  #00BFC4  42  151336.13587     1     2
## 43  #F8766D  43  108122.81907     1     1
## 44  #00BFC4  44   38005.48600     1     2
## 45  #F8766D  45  138750.60638     1     1
## 46  #00BFC4  46  105880.33312     1     2
## 47  #F8766D  47  172220.31845     1     1
## 48  #00BFC4  48  166652.15369     1     2
## 49  #F8766D  49  125860.04342     1     1
## 50  #00BFC4  50  128807.63745     1     2
## 51  #F8766D  51  150030.22974     1     1
## 52  #00BFC4  52  156734.97163     1     2
## 53  #F8766D  53  245768.82089     1     1
## 54  #00BFC4  54  293062.82187     1     2
## 55  #F8766D  55  178917.33063     1     1
## 56  #00BFC4  56  288374.87380     1     2
## 57  #F8766D  57  254755.27055     1     1
## 58  #00BFC4  58  123199.36853     1     2
## 59  #F8766D  59  274487.91623     1     1
## 60  #00BFC4  60  222623.20984     1     2
## 61  #F8766D  61  222842.96771     1     1
## 62  #00BFC4  62  241015.87419     1     2
## 63  #F8766D  63  220328.38018     1     1
## 64  #00BFC4  64  318806.51984     1     2
## 65  #F8766D  65  272864.11128     1     1
## 66  #00BFC4  66  265162.41694     1     2
## 67  #F8766D  67  255642.47850     1     1
## 68  #00BFC4  68  322194.31154     1     2
## 69  #F8766D  69  347017.72201     1     1
## 70  #00BFC4  70  359621.14058     1     2
## 71  #F8766D  71  409505.44488     1     1
## 72  #00BFC4  72  295070.27132     1     2
## 73  #F8766D  73  358004.66398     1     1
## 74  #00BFC4  74  459490.18232     1     2
## 75  #F8766D  75  486672.38910     1     1
## 76  #00BFC4  76  409640.42160     1     2
## 77  #F8766D  77  475457.21816     1     1
## 78  #00BFC4  78  508282.47227     1     2
## 79  #F8766D  79  511276.10109     1     1
## 80  #00BFC4  80  459354.48209     1     2
## 81  #F8766D  81  381879.15102     1     1
## 82  #00BFC4  82  594162.52358     1     2
## 83  #F8766D  83  580768.97604     1     1
## 84  #00BFC4  84  718909.76743     1     2
## 85  #F8766D  85  465913.07527     1     1
## 86  #00BFC4  86  680853.27505     1     2
## 87  #F8766D  87  745596.30841     1     1
## 88  #00BFC4  88  620977.11497     1     2
## 89  #F8766D  89  691123.81099     1     1
## 90  #00BFC4  90  739921.53095     1     2
## 91  #F8766D  91  724468.12123     1     1
## 92  #00BFC4  92  720974.71398     1     2
## 93  #F8766D  93  823013.91892     1     1
## 94  #00BFC4  94  829332.45926     1     2
## 95  #F8766D  95  984858.01120     1     1
## 96  #00BFC4  96  977486.03153     1     2
## 97  #F8766D  97  818881.35514     1     1
## 98  #00BFC4  98 1058604.36945     1     2
## 99  #F8766D  99  977556.06367     1     1
## 100 #00BFC4 100 1077468.45449     1     2

ggplot(my.data, aes(x, y, colour = group)) + geom_point() + 
  geom_debug(summary.fun = NULL)
##      colour   x             y PANEL group
## 1   #F8766D   1  -27205.45039     1     1
## 2   #00BFC4   2  -14242.65108     1     2
## 3   #F8766D   3   45790.91787     1     1
## 4   #00BFC4   4   53731.42037     1     2
## 5   #F8766D   5   -8028.57848     1     1
## 6   #00BFC4   6  102863.94292     1     2
## 7   #F8766D   7  -18547.28227     1     1
## 8   #00BFC4   8   13080.52133     1     2
## 9   #F8766D   9   79924.32504     1     1
## 10  #00BFC4  10  -44711.49916     1     2
## 11  #F8766D  11   -2823.73559     1     1
## 12  #00BFC4  12   23839.55471     1     2
## 13  #F8766D  13  -78016.69001     1     1
## 14  #00BFC4  14   75601.95706     1     2
## 15  #F8766D  15  -74281.23373     1     1
## 16  #00BFC4  16  104676.72111     1     2
## 17  #F8766D  17    9903.67373     1     1
## 18  #00BFC4  18  -68746.93124     1     2
## 19  #F8766D  19  -94022.62267     1     1
## 20  #00BFC4  20  -39230.19259     1     2
## 21  #F8766D  21   40550.54085     1     1
## 22  #00BFC4  22   10961.10296     1     2
## 23  #F8766D  23   12149.63105     1     1
## 24  #00BFC4  24   52254.25671     1     2
## 25  #F8766D  25    9950.24731     1     1
## 26  #00BFC4  26    3101.82898     1     2
## 27  #F8766D  27   23485.44314     1     1
## 28  #00BFC4  28   41668.54023     1     2
## 29  #F8766D  29  -27901.59355     1     1
## 30  #00BFC4  30  -59669.17456     1     2
## 31  #F8766D  31   39726.66001     1     1
## 32  #00BFC4  32   76038.66842     1     2
## 33  #F8766D  33  109169.84766     1     1
## 34  #00BFC4  34   10202.63915     1     2
## 35  #F8766D  35   98481.72725     1     1
## 36  #00BFC4  36      73.97657     1     2
## 37  #F8766D  37   40859.18209     1     1
## 38  #00BFC4  38  104296.43202     1     2
## 39  #F8766D  39   76002.67764     1     1
## 40  #00BFC4  40  146450.81373     1     2
## 41  #F8766D  41   61283.85767     1     1
## 42  #00BFC4  42  151336.13587     1     2
## 43  #F8766D  43  108122.81907     1     1
## 44  #00BFC4  44   38005.48600     1     2
## 45  #F8766D  45  138750.60638     1     1
## 46  #00BFC4  46  105880.33312     1     2
## 47  #F8766D  47  172220.31845     1     1
## 48  #00BFC4  48  166652.15369     1     2
## 49  #F8766D  49  125860.04342     1     1
## 50  #00BFC4  50  128807.63745     1     2
## 51  #F8766D  51  150030.22974     1     1
## 52  #00BFC4  52  156734.97163     1     2
## 53  #F8766D  53  245768.82089     1     1
## 54  #00BFC4  54  293062.82187     1     2
## 55  #F8766D  55  178917.33063     1     1
## 56  #00BFC4  56  288374.87380     1     2
## 57  #F8766D  57  254755.27055     1     1
## 58  #00BFC4  58  123199.36853     1     2
## 59  #F8766D  59  274487.91623     1     1
## 60  #00BFC4  60  222623.20984     1     2
## 61  #F8766D  61  222842.96771     1     1
## 62  #00BFC4  62  241015.87419     1     2
## 63  #F8766D  63  220328.38018     1     1
## 64  #00BFC4  64  318806.51984     1     2
## 65  #F8766D  65  272864.11128     1     1
## 66  #00BFC4  66  265162.41694     1     2
## 67  #F8766D  67  255642.47850     1     1
## 68  #00BFC4  68  322194.31154     1     2
## 69  #F8766D  69  347017.72201     1     1
## 70  #00BFC4  70  359621.14058     1     2
## 71  #F8766D  71  409505.44488     1     1
## 72  #00BFC4  72  295070.27132     1     2
## 73  #F8766D  73  358004.66398     1     1
## 74  #00BFC4  74  459490.18232     1     2
## 75  #F8766D  75  486672.38910     1     1
## 76  #00BFC4  76  409640.42160     1     2
## 77  #F8766D  77  475457.21816     1     1
## 78  #00BFC4  78  508282.47227     1     2
## 79  #F8766D  79  511276.10109     1     1
## 80  #00BFC4  80  459354.48209     1     2
## 81  #F8766D  81  381879.15102     1     1
## 82  #00BFC4  82  594162.52358     1     2
## 83  #F8766D  83  580768.97604     1     1
## 84  #00BFC4  84  718909.76743     1     2
## 85  #F8766D  85  465913.07527     1     1
## 86  #00BFC4  86  680853.27505     1     2
## 87  #F8766D  87  745596.30841     1     1
## 88  #00BFC4  88  620977.11497     1     2
## 89  #F8766D  89  691123.81099     1     1
## 90  #00BFC4  90  739921.53095     1     2
## 91  #F8766D  91  724468.12123     1     1
## 92  #00BFC4  92  720974.71398     1     2
## 93  #F8766D  93  823013.91892     1     1
## 94  #00BFC4  94  829332.45926     1     2
## 95  #F8766D  95  984858.01120     1     1
## 96  #00BFC4  96  977486.03153     1     2
## 97  #F8766D  97  818881.35514     1     1
## 98  #00BFC4  98 1058604.36945     1     2
## 99  #F8766D  99  977556.06367     1     1
## 100 #00BFC4 100 1077468.45449     1     2

And also to print to the console the data returned by a stat.

ggplot(my.data, aes(x, y, colour = group)) + geom_point() + 
  stat_smooth(method = "lm", geom = "debug")
## # A tibble: 160 x 8
##    colour      x        y     ymin     ymax     se PANEL group
##    <chr>   <dbl>    <dbl>    <dbl>    <dbl>  <dbl> <fct> <int>
##  1 #F8766D  1    -188136. -254711. -121562. 33111. 1         1
##  2 #F8766D  2.24 -176933. -242260. -111606. 32491. 1         1
##  3 #F8766D  3.48 -165730. -229819. -101641. 31875. 1         1
##  4 #F8766D  4.72 -154527. -217387.  -91668. 31263. 1         1
##  5 #F8766D  5.96 -143324. -204964.  -81684. 30657. 1         1
##  6 #F8766D  7.20 -132121. -192552.  -71691. 30055. 1         1
##  7 #F8766D  8.44 -120918. -180150.  -61686. 29459. 1         1
##  8 #F8766D  9.68 -109715. -167760.  -51670. 28869. 1         1
##  9 #F8766D 10.9   -98512. -155383.  -41642. 28285. 1         1
## 10 #F8766D 12.2   -87309. -143019.  -31600. 27707. 1         1
## # ... with 150 more rows

ggplot(my.data, aes(x, y, colour = group)) + geom_point() + 
  stat_peaks(span = NULL, geom = "debug")
## # A tibble: 2 x 10
##   colour  xintercept yintercept label     x        y PANEL group x.label
##   <chr>        <dbl>      <dbl> <chr> <dbl>    <dbl> <fct> <int> <chr>  
## 1 #F8766D         95    984858. 95       95  984858. 1         1 95     
## 2 #00BFC4        100   1077468. 100     100 1077468. 1         2 100    
## # ... with 1 more variable: y.label <chr>

formula <- y ~ poly(x, 3, raw = TRUE)
ggplot(my.data, aes(x, y)) +
  stat_fit_residuals(formula = formula, geom = "debug", 
                     summary.fun = head, summary.fun.args = list(n = 12))
##     x          y    y.resid y.resid.abs PANEL group
## 1   1 -23513.687 -23513.687   23513.687     1    -1
## 2   2 -11663.732 -11663.732   11663.732     1    -1
## 3   3  47289.460  47289.460   47289.460     1    -1
## 4   4  54175.231  54175.231   54175.231     1    -1
## 5   5  -8620.676  -8620.676    8620.676     1    -1
## 6   6 101247.937 101247.937  101247.937     1    -1
## 7   7 -21182.019 -21182.019   21182.019     1    -1
## 8   8   9425.407   9425.407    9425.407     1    -1
## 9   9  75240.365  75240.365   75240.365     1    -1
## 10 10 -50439.597 -50439.597   50439.597     1    -1
## 11 11  -9618.085  -9618.085    9618.085     1    -1
## 12 12  15950.016  15950.016   15950.016     1    -1

formula <- y ~ x + I(x^2) + I(x^3)
ggplot(my.data, aes(x, y)) +
  geom_point() +
  stat_fit_augment(method = "lm", 
                   method.args = list(formula = formula),
                   geom = "debug") +
  stat_fit_augment(method = "lm", 
                   method.args = list(formula = formula),
                   geom = "smooth")
## # A tibble: 100 x 17
##       ymin   ymax      y     x I.x.2. I.x.3. .fitted .se.fit   .resid
##      <dbl>  <dbl>  <dbl> <dbl>  <dbl>  <dbl>   <dbl>   <dbl>    <dbl>
##  1 -48698. 41315. -3692.     1      1      1  -3692.  22673.  -23514.
##  2 -44308. 39151. -2579.     2      4      8  -2579.  21023.  -11664.
##  3 -40182. 37185. -1499.     3      9     27  -1499.  19488.   47289.
##  4 -36314. 35426.  -444.     4     16     64   -444.  18071.   54175.
##  5 -32701. 33885.   592.     5     25    125    592.  16772.   -8621.
##  6 -29339. 32571.  1616.     6     36    216   1616.  15594.  101248.
##  7 -26223. 31493.  2635.     7     49    343   2635.  14538.  -21182.
##  8 -23349. 30659.  3655.     8     64    512   3655.  13604.    9425.
##  9 -20709. 30077.  4684.     9     81    729   4684.  12792.   75240.
## 10 -18293. 29749.  5728.    10    100   1000   5728.  12101.  -50440.
## # ... with 90 more rows, and 8 more variables: .hat <dbl>, .sigma <dbl>,
## #   .cooksd <dbl>, .std.resid <dbl>, y.observed <dbl>, t.value <dbl>,
## #   PANEL <fct>, group <int>

formula <- y ~ x + I(x^2) + I(x^3)
ggplot(my.data, aes(x, y2, colour = group)) +
  geom_point() +
  stat_fit_augment(method = "lm", 
                   method.args = list(formula = formula),
                   geom = "debug") +
  stat_fit_augment(method = "lm", 
                   method.args = list(formula = formula),
                   geom = "smooth")
## # A tibble: 100 x 19
##    colour     ymin   ymax .rownames       y     x I.x.2. I.x.3. .fitted
##    <chr>     <dbl>  <dbl> <chr>       <dbl> <dbl>  <dbl>  <dbl>   <dbl>
##  1 #F8766D -41080. 20399. 1         -10340.     1      1      1 -10340.
##  2 #F8766D -35274. 17555. 3          -8860.     3      9     27  -8860.
##  3 #F8766D -30156. 15353. 5          -7402.     5     25    125  -7402.
##  4 #F8766D -25720. 13833. 7          -5943.     7     49    343  -5943.
##  5 #F8766D -21946. 13026. 9          -4460.     9     81    729  -4460.
##  6 #F8766D -18794. 12937. 11         -2928.    11    121   1331  -2928.
##  7 #F8766D -16176. 13528. 13         -1324.    13    169   2197  -1324.
##  8 #F8766D -13958. 14712. 15           377.    15    225   3375    377.
##  9 #F8766D -11979. 16376. 17          2199.    17    289   4913   2199.
## 10 #F8766D -10073. 18403. 19          4165.    19    361   6859   4165.
## # ... with 90 more rows, and 10 more variables: .se.fit <dbl>,
## #   .resid <dbl>, .hat <dbl>, .sigma <dbl>, .cooksd <dbl>,
## #   .std.resid <dbl>, y.observed <dbl>, t.value <dbl>, PANEL <fct>,
## #   group <int>

The ‘ggpmisc’ package also defines a "null" geom, which is used as default by the debug stats described above. Currently this geom is similar to the recently added ggplot2::geom_blank().

ggplot(my.data, aes(x, y, colour = group)) + geom_null()