1#' Scales for shapes, aka glyphs
2#'
3#' `scale_shape()` maps discrete variables to six easily discernible shapes.
4#' If you have more than six levels, you will get a warning message, and the
5#' seventh and subsequent levels will not appear on the plot. Use
6#' [scale_shape_manual()] to supply your own values. You can not map
7#' a continuous variable to shape unless `scale_shape_binned()` is used. Still,
8#' as shape has no inherent order, this use is not advised.
9#'
10#' @param solid Should the shapes be solid, `TRUE`, or hollow,
11#'   `FALSE`?
12#' @inheritParams scale_x_discrete
13#' @inheritDotParams discrete_scale -expand -position
14#' @rdname scale_shape
15#' @export
16#' @examples
17#' dsmall <- diamonds[sample(nrow(diamonds), 100), ]
18#'
19#' (d <- ggplot(dsmall, aes(carat, price)) + geom_point(aes(shape = cut)))
20#' d + scale_shape(solid = TRUE) # the default
21#' d + scale_shape(solid = FALSE)
22#' d + scale_shape(name = "Cut of diamond")
23#'
24#' # To change order of levels, change order of
25#' # underlying factor
26#' levels(dsmall$cut) <- c("Fair", "Good", "Very Good", "Premium", "Ideal")
27#'
28#' # Need to recreate plot to pick up new data
29#' ggplot(dsmall, aes(price, carat)) + geom_point(aes(shape = cut))
30#'
31#' # Show a list of available shapes
32#' df_shapes <- data.frame(shape = 0:24)
33#' ggplot(df_shapes, aes(0, 0, shape = shape)) +
34#'   geom_point(aes(shape = shape), size = 5, fill = 'red') +
35#'   scale_shape_identity() +
36#'   facet_wrap(~shape) +
37#'   theme_void()
38scale_shape <- function(..., solid = TRUE) {
39  discrete_scale("shape", "shape_d", shape_pal(solid), ...)
40}
41
42#' @rdname scale_shape
43#' @export
44scale_shape_binned <- function(..., solid = TRUE) {
45  binned_scale("shape", "shape_b", binned_pal(shape_pal(solid)), ...)
46}
47
48#' @rdname scale_shape
49#' @export
50#' @usage NULL
51scale_shape_discrete <- scale_shape
52
53#' @rdname scale_shape
54#' @export
55#' @usage NULL
56scale_shape_ordinal <- function(...) {
57  warn("Using shapes for an ordinal variable is not advised")
58  scale_shape(...)
59}
60
61#' @rdname scale_shape
62#' @export
63#' @usage NULL
64scale_shape_continuous <- function(...) {
65  abort("A continuous variable can not be mapped to shape")
66}
67