1#' Create a new ggplot
2#'
3#' `ggplot()` initializes a ggplot object. It can be used to
4#' declare the input data frame for a graphic and to specify the
5#' set of plot aesthetics intended to be common throughout all
6#' subsequent layers unless specifically overridden.
7#'
8#' `ggplot()` is used to construct the initial plot object,
9#' and is almost always followed by `+` to add component to the
10#' plot. There are three common ways to invoke `ggplot()`:
11#'
12#' * `ggplot(df, aes(x, y, other aesthetics))`
13#' * `ggplot(df)`
14#' * `ggplot()`
15#'
16#' The first method is recommended if all layers use the same
17#' data and the same set of aesthetics, although this method
18#' can also be used to add a layer using data from another
19#' data frame. See the first example below. The second
20#' method specifies the default data frame to use for the plot,
21#' but no aesthetics are defined up front. This is useful when
22#' one data frame is used predominantly as layers are added,
23#' but the aesthetics may vary from one layer to another. The
24#' third method initializes a skeleton `ggplot` object which
25#' is fleshed out as layers are added. This method is useful when
26#' multiple data frames are used to produce different layers, as
27#' is often the case in complex graphics.
28#'
29#' @param data Default dataset to use for plot. If not already a data.frame,
30#'   will be converted to one by [fortify()]. If not specified,
31#'   must be supplied in each layer added to the plot.
32#' @param mapping Default list of aesthetic mappings to use for plot.
33#'   If not specified, must be supplied in each layer added to the plot.
34#' @param ... Other arguments passed on to methods. Not currently used.
35#' @param environment DEPRECATED. Used prior to tidy evaluation.
36#' @export
37#' @examples
38#' # Generate some sample data, then compute mean and standard deviation
39#' # in each group
40#' df <- data.frame(
41#'   gp = factor(rep(letters[1:3], each = 10)),
42#'   y = rnorm(30)
43#' )
44#' ds <- do.call(rbind, lapply(split(df, df$gp), function(d) {
45#'   data.frame(mean = mean(d$y), sd = sd(d$y), gp = d$gp)
46#' }))
47#'
48#' # The summary data frame ds is used to plot larger red points on top
49#' # of the raw data. Note that we don't need to supply `data` or `mapping`
50#' # in each layer because the defaults from ggplot() are used.
51#' ggplot(df, aes(gp, y)) +
52#'   geom_point() +
53#'   geom_point(data = ds, aes(y = mean), colour = 'red', size = 3)
54#'
55#' # Same plot as above, declaring only the data frame in ggplot().
56#' # Note how the x and y aesthetics must now be declared in
57#' # each geom_point() layer.
58#' ggplot(df) +
59#'   geom_point(aes(gp, y)) +
60#'   geom_point(data = ds, aes(gp, mean), colour = 'red', size = 3)
61#'
62#' # Alternatively we can fully specify the plot in each layer. This
63#' # is not useful here, but can be more clear when working with complex
64#' # mult-dataset graphics
65#' ggplot() +
66#'   geom_point(data = df, aes(gp, y)) +
67#'   geom_point(data = ds, aes(gp, mean), colour = 'red', size = 3) +
68#'   geom_errorbar(
69#'     data = ds,
70#'     aes(gp, mean, ymin = mean - sd, ymax = mean + sd),
71#'     colour = 'red',
72#'     width = 0.4
73#'   )
74ggplot <- function(data = NULL, mapping = aes(), ...,
75                   environment = parent.frame()) {
76  UseMethod("ggplot")
77}
78
79#' @export
80ggplot.default <- function(data = NULL, mapping = aes(), ...,
81                           environment = parent.frame()) {
82  if (!missing(mapping) && !inherits(mapping, "uneval")) {
83    abort("Mapping should be created with `aes()` or `aes_()`.")
84  }
85
86  data <- fortify(data, ...)
87
88  p <- structure(list(
89    data = data,
90    layers = list(),
91    scales = scales_list(),
92    mapping = mapping,
93    theme = list(),
94    coordinates = coord_cartesian(default = TRUE),
95    facet = facet_null(),
96    plot_env = environment
97  ), class = c("gg", "ggplot"))
98
99  p$labels <- make_labels(mapping)
100
101  set_last_plot(p)
102  p
103}
104
105#' @export
106ggplot.function <- function(data = NULL, mapping = aes(), ...,
107                            environment = parent.frame()) {
108  # Added to avoid functions end in ggplot.default
109  abort(glue("
110    You're passing a function as global data.
111    Have you misspelled the `data` argument in `ggplot()`
112  "))
113}
114
115plot_clone <- function(plot) {
116  p <- plot
117  p$scales <- plot$scales$clone()
118
119  p
120}
121
122#' Reports whether x is a ggplot object
123#' @param x An object to test
124#' @keywords internal
125#' @export
126is.ggplot <- function(x) inherits(x, "ggplot")
127
128#' Explicitly draw plot
129#'
130#' Generally, you do not need to print or plot a ggplot2 plot explicitly: the
131#' default top-level print method will do it for you. You will, however, need
132#' to call `print()` explicitly if you want to draw a plot inside a
133#' function or for loop.
134#'
135#' @param x plot to display
136#' @param newpage draw new (empty) page first?
137#' @param vp viewport to draw plot in
138#' @param ... other arguments not used by this method
139#' @keywords hplot
140#' @return Invisibly returns the result of [ggplot_build()], which
141#'   is a list with components that contain the plot itself, the data,
142#'   information about the scales, panels etc.
143#' @export
144#' @method print ggplot
145#' @examples
146#' colours <- list(~class, ~drv, ~fl)
147#'
148#' # Doesn't seem to do anything!
149#' for (colour in colours) {
150#'   ggplot(mpg, aes_(~ displ, ~ hwy, colour = colour)) +
151#'     geom_point()
152#' }
153#'
154#' # Works when we explicitly print the plots
155#' for (colour in colours) {
156#'   print(ggplot(mpg, aes_(~ displ, ~ hwy, colour = colour)) +
157#'     geom_point())
158#' }
159print.ggplot <- function(x, newpage = is.null(vp), vp = NULL, ...) {
160  set_last_plot(x)
161  if (newpage) grid.newpage()
162
163  # Record dependency on 'ggplot2' on the display list
164  # (AFTER grid.newpage())
165  grDevices::recordGraphics(
166    requireNamespace("ggplot2", quietly = TRUE),
167    list(),
168    getNamespace("ggplot2")
169  )
170
171  data <- ggplot_build(x)
172
173  gtable <- ggplot_gtable(data)
174  if (is.null(vp)) {
175    grid.draw(gtable)
176  } else {
177    if (is.character(vp)) seekViewport(vp) else pushViewport(vp)
178    grid.draw(gtable)
179    upViewport()
180  }
181
182  if (isTRUE(getOption("BrailleR.VI")) && rlang::is_installed("BrailleR")) {
183    print(asNamespace("BrailleR")$VI(x))
184  }
185
186  invisible(x)
187}
188#' @rdname print.ggplot
189#' @method plot ggplot
190#' @export
191plot.ggplot <- print.ggplot
192