├── .DS_Store
├── .Rbuildignore
├── .covrignore
├── .gitignore
├── .travis.yml
├── DESCRIPTION
├── LICENSE
├── LICENSE.md
├── NAMESPACE
├── R
├── Hypotrochoid.R
├── aaa.R
├── epitrochoid.R
├── ggpronto-classes.R
├── lissajous.R
├── rose.R
├── shape.R
└── star.R
├── README.Rmd
├── README.md
├── _pkgdown.yml
├── codecov.yml
├── cran-comments.md
├── ggshapes.Rproj
└── man
├── example.gif
├── figures
├── README-example-1.png
├── README-unnamed-chunk-2-1.png
├── README-unnamed-chunk-3-1.png
├── README-unnamed-chunk-4-1.png
└── README-unnamed-chunk-5-1.png
├── geom_epitrochoid.Rd
├── geom_hypotrochoid.Rd
├── geom_lissajous.Rd
├── geom_rose.Rd
├── geom_star.Rd
├── ggshapes-extensions.Rd
├── rotate_df.Rd
└── weave.Rd
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EmilHvitfeldt/ggshapes/f9cd15572fe7c05b6b408f4f384610725338bd94/.DS_Store
--------------------------------------------------------------------------------
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^cran-comments\.md$
2 | ^\.covrignore$
3 | ^codecov\.yml$
4 | ^\.travis\.yml$
5 | ^README\.Rmd$
6 | ^LICENSE\.md$
7 | ^ggshapes\.Rproj$
8 | ^\.Rproj\.user$
9 | ^_pkgdown\.yml$
10 |
--------------------------------------------------------------------------------
/.covrignore:
--------------------------------------------------------------------------------
1 | R/deprec-*.R
2 | R/compat-*.R
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r
2 |
3 | language: R
4 | cache: packages
5 |
6 | r_github_packages:
7 | - r-lib/pkgdown
8 |
9 | matrix:
10 | include:
11 | - r: devel
12 | - r: release
13 | after_success:
14 | - Rscript -e 'covr::codecov()'
15 |
16 | deploy:
17 | provider: script
18 | script: Rscript -e 'pkgdown::deploy_site_github(verbose = TRUE, run_dont_run = TRUE)'
19 | skip_cleanup: true
20 | - r: oldrel
21 | - r: 3.3
22 | - r: 3.2
23 | - r: 3.1
24 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: ggshapes
2 | Title: Adds Geoms That Produces Shapes And Curves
3 | Version: 0.0.0.9000
4 | Authors@R:
5 | person(given = "Emil",
6 | family = "Hvitfeldt",
7 | role = c("aut", "cre"),
8 | email = "emilhhvitfeldt@gmail.com")
9 | Description: This will add various practical and impractical shapes to be
10 | produced in 'ggplot2'. These shapes and curves will complement the
11 | circle and regular polygon geoms in the 'ggforce' package.
12 | URL: https://github.com/EmilHvitfeldt/ggshapes
13 | BugReports: https://github.com/EmilHvitfeldt/ggshapes/issues
14 | License: MIT + file LICENSE
15 | Encoding: UTF-8
16 | LazyData: true
17 | Depends:
18 | ggplot2 (>= 2.2.0),
19 | R (>= 3.1)
20 | RoxygenNote: 6.1.1
21 | Suggests:
22 | covr
23 | Imports:
24 | tidyr
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2019
2 | COPYRIGHT HOLDER: Emil Hvitfeldt
3 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2019 Emil Hvitfeldt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | export(GeomShape)
4 | export(StatEpitrochoid)
5 | export(StatHypotrochoid)
6 | export(StatLissajous)
7 | export(StatRose)
8 | export(StatStar)
9 | export(geom_epitrochoid)
10 | export(geom_hypotrochoid)
11 | export(geom_lissajous)
12 | export(geom_rose)
13 | export(geom_star)
14 | export(stat_epitrochoid)
15 | export(stat_hypotrochoid)
16 | export(stat_lissajous)
17 | export(stat_rose)
18 | export(stat_star)
19 | importFrom(ggplot2,Stat)
20 | importFrom(ggplot2,aes)
21 | importFrom(ggplot2,ggproto)
22 | importFrom(ggplot2,layer)
23 |
--------------------------------------------------------------------------------
/R/Hypotrochoid.R:
--------------------------------------------------------------------------------
1 | #' Draw a rose or Hypotrochoid curve
2 | #'
3 | #' This geom allows you to draw the hypotrochoid curve. A hypotrochoid is a
4 | #' curve traced by a point attached to a circle of radius r_min rolling around
5 | #' the inside of a fixed circle of radius r_max, where the point is at a
6 | #' distance h from the center of the interior circle.
7 | #'
8 | #' To unscale the curve, please set xscale and yscale to abs(r_max - r_min) + h.
9 | #'
10 | #' The curve follows the the parameterized form
11 | #'
12 | #' \deqn{x = (r_max - r_min) cos(\theta) + h * cos(\frac{r_max - r_min}{r_min} \theta)}
13 | #' \deqn{x = (r_max - r_min) sin(\theta) + h * sin(\frac{r_max - r_min}{r_min} \theta)}
14 | #'
15 | #' these curves are closed when the radion \eqn{a / b} is rational. delta have
16 | #' been scaled to be in the interval [0, 1].
17 | #'
18 | #' @references \url{https://en.wikipedia.org/wiki/Hypocycloid}
19 | #' \url{http://xahlee.info/SpecialPlaneCurves_dir/Hypotrochoid_dir/hypotrochoid.html}
20 | #' @section Aesthetics:
21 | #' geom_arc understand the following aesthetics (required aesthetics are in
22 | #' bold):
23 | #'
24 | #' - **r_max**
25 | #' - **r_min**
26 | #' - h
27 | #' - x0
28 | #' - y0
29 | #' - xscale
30 | #' - yscale
31 | #' - rotation
32 | #' - color
33 | #' - fill
34 | #' - size
35 | #' - linetype
36 | #' - alpha
37 | #' - lineend
38 | #'
39 | #' @section Computed variables:
40 | #'
41 | #' \describe{
42 | #' \item{x, y}{The coordinates for the points along the rose curve}
43 | #' }
44 | #'
45 | #' @inheritParams ggplot2::geom_path
46 | #' @inheritParams ggplot2::stat_identity
47 | #'
48 | #' @param n_points The number of points to sample along the curve.
49 | #'
50 | #' @author Emil Hvitfeldt
51 | #'
52 | #' @name geom_hypotrochoid
53 | #' @rdname geom_hypotrochoid
54 | #' @seealso [geom_epitrochoid()]
55 | #'
56 | #' @examples
57 | #'
58 | #' # When h is missing a hypocycloid is generated
59 | #' ggplot() +
60 | #' geom_hypotrochoid(aes(r_max = 4, r_min = 1))
61 | #'
62 | #' ggplot() +
63 | #' geom_hypotrochoid(aes(r_max = 8, r_min = 1))
64 | #'
65 | #' ggplot() +
66 | #' geom_hypotrochoid(aes(r_max = c(4, 6, 8), r_min = 1))
67 | #'
68 | #' # specifying h
69 | #' ggplot() +
70 | #' geom_hypotrochoid(aes(r_max = 4, r_min = 9, h = 4))
71 | #'
72 | #' ggplot() +
73 | #' geom_hypotrochoid(aes(r_max = 4, r_min = 3, h = 20 / 13))
74 | #'
75 | #' # changing rotation
76 | #' ggplot() +
77 | #' geom_hypotrochoid(aes(r_max = 4, r_min = 1, rotation = pi / 4))
78 | #'
79 | #' # When things go wild
80 | #' ggplot(expand.grid(seq(4, 20, by = 2), c(1, 3, 5, 9))) +
81 | #' geom_hypotrochoid(aes(r_max = Var1, r_min = Var2, color = Var1,
82 | #' xscale = abs(Var1 - Var2) + Var2,
83 | #' yscale = abs(Var1 - Var2) + Var2)) +
84 | #' coord_fixed() +
85 | #' theme_minimal() +
86 | #' scale_color_viridis_c(option = "B") +
87 | #' guides(color = "none") +
88 | #' facet_wrap(~ Var2)
89 | NULL
90 |
91 | #' @rdname ggshapes-extensions
92 | #' @format NULL
93 | #' @usage NULL
94 | #' @importFrom ggplot2 ggproto Stat aes
95 | #' @export
96 | StatHypotrochoid <- ggproto('StatHypotrochoid', Stat,
97 | compute_layer = function(self, data, params, layout) {
98 | if (is.null(data)) return(data)
99 | if (is.null(data$x0)) data$x0 <- 0
100 | if (is.null(data$y0)) data$y0 <- 0
101 | if (is.null(data$xscale)) data$xscale <- 1
102 | if (is.null(data$yscale)) data$yscale <- 1
103 | if (is.null(data$h)) data$h <- data$r_min
104 | if (is.null(data$rotation)) data$rotation <- 0
105 | data$group <- seq_len(nrow(data))
106 |
107 | data <- tidyr::nest(data, r_min, r_max, h, x0, y0, xscale, yscale, rotation)
108 | data$data <- lapply(data$data, hypotrochoid_calc, params = params)
109 | tidyr::unnest(data)
110 | },
111 | required_aes = c('r_min', 'r_max'),
112 | default_aes = aes(x0 = 0, y0 = 0, h = NULL, xscale = 1, yscale = 1, rotation = 0),
113 | extra_params = c('n_points', 'na.rm')
114 | )
115 |
116 | hypotrochoid_calc <- function(data, params) {
117 | t <- seq(from = 0, to = 2 * pi * data$r_min, length.out = params$n_points)
118 |
119 | out <- data.frame(
120 | x = data$x0 + data$xscale * ((data$r_max - data$r_min) * cos(t) +
121 | data$h * cos((data$r_max - data$r_min) / data$r_min * t)) / (abs(data$r_max - data$r_min) + data$h),
122 | y = data$y0 + data$yscale * ((data$r_max - data$r_min) * sin(t) -
123 | data$h * sin((data$r_max - data$r_min) / data$r_min * t)) / (abs(data$r_max - data$r_min) + data$h)
124 | )
125 |
126 | rotate_df(out, data$rotation)
127 | }
128 |
129 | #' @rdname geom_hypotrochoid
130 | #' @importFrom ggplot2 layer
131 | #' @export
132 | stat_hypotrochoid <- function(mapping = NULL, data = NULL, geom = "hypotrochoid",
133 | position = "identity", n_points = 360, na.rm = FALSE, show.legend = NA,
134 | inherit.aes = TRUE, ...) {
135 | layer(
136 | stat = StatHypotrochoid, data = data, mapping = mapping, geom = geom,
137 | position = position, show.legend = show.legend, inherit.aes = inherit.aes,
138 | params = list(na.rm = na.rm, n_points = n_points, ...)
139 | )
140 | }
141 |
142 | #' @rdname geom_hypotrochoid
143 | #' @importFrom ggplot2 layer
144 | #' @export
145 | geom_hypotrochoid <- function(mapping = NULL, data = NULL, stat = "hypotrochoid",
146 | position = "identity", n_points = 360, na.rm = FALSE,
147 | show.legend = NA, inherit.aes = TRUE, ...) {
148 | layer(data = data, mapping = mapping, stat = stat, geom = GeomShape,
149 | position = position, show.legend = show.legend, inherit.aes = inherit.aes,
150 | params = list(n_points = n_points, na.rm = na.rm, ...))
151 | }
152 |
--------------------------------------------------------------------------------
/R/aaa.R:
--------------------------------------------------------------------------------
1 | #' Weaves two vectors together using alternating indecies
2 | #'
3 | #' @param a Vector
4 | #' @param b Vector
5 |
6 | #' @return A vector
7 | weave <- function(a, b) {
8 | x <- vector(class(a), length(c(a, b)))
9 | x[c(TRUE, FALSE)] <- a
10 | x[c(FALSE, TRUE)] <- b
11 | x
12 | }
13 |
14 | #' Rotates a parametric data.frame
15 | #'
16 | #' @param df a data frame with two columns x and y
17 | #' @param theta a numeric denoting the amount of rotation
18 | #'
19 | #' @return a data frame with two columns x and y
20 | rotate_df <- function(df, theta) {
21 | if (theta %% (pi * 2) == 0) {
22 | return(df)
23 | }
24 | out <- df
25 | out$x <- df$x * cos(theta) - df$y * sin(theta)
26 | out$y <- df$x * sin(theta) + df$y * cos(theta)
27 | out
28 | }
29 |
--------------------------------------------------------------------------------
/R/epitrochoid.R:
--------------------------------------------------------------------------------
1 | #' Draw a rose or Epitrochoid curve
2 | #'
3 | #' This geom allows you to draw the epitrochoid curve. A epitrochoid is a
4 | #' curve traced by a point attached to a circle of radius r_min rolling around
5 | #' the outside of a fixed circle of radius r_max, where the point is at a
6 | #' distance h from the center of the interior circle. h is the same as r_min
7 | #' by default.
8 | #'
9 | #' To unscale the curve, please set xscale and yscale to r_max + r_min + h.
10 | #'
11 | #' The curve follows the the parameterized form
12 | #'
13 | #' \deqn{x = (r_max + r_min) cos(\theta) - h * cos(\frac{r_max + r_min}{r_min} \theta)}
14 | #' \deqn{x = (r_max + r_min) sin(\theta) - h * sin(\frac{r_max + r_min}{r_min} \theta)}
15 | #'
16 | #' these curves are closed when the radion \eqn{a / b} is rational. delta have
17 | #' been scaled to be in the interval [0, 1].
18 | #'
19 | #' @references \url{http://mathworld.wolfram.com/Epitrochoid.html}
20 | #' \url{http://xahlee.info/SpecialPlaneCurves_dir/Epitrochoid_dir/epitrochoid.html}
21 | #' @section Aesthetics:
22 | #' geom_arc understand the following aesthetics (required aesthetics are in
23 | #' bold):
24 | #'
25 | #' - **r_max**
26 | #' - **r_min**
27 | #' - h
28 | #' - x0
29 | #' - y0
30 | #' - xscale
31 | #' - yscale
32 | #' - rotation
33 | #' - color
34 | #' - fill
35 | #' - size
36 | #' - linetype
37 | #' - alpha
38 | #' - lineend
39 | #'
40 | #' @section Computed variables:
41 | #'
42 | #' \describe{
43 | #' \item{x, y}{The coordinates for the points along the rose curve}
44 | #' }
45 | #'
46 | #' @inheritParams ggplot2::geom_path
47 | #' @inheritParams ggplot2::stat_identity
48 | #'
49 | #' @param n_points The number of points to sample along the curve.
50 | #'
51 | #' @author Emil Hvitfeldt
52 | #'
53 | #' @name geom_epitrochoid
54 | #' @rdname geom_epitrochoid
55 | #' @seealso [geom_hypotrochoid()]
56 | #'
57 | #' @examples
58 | #'
59 | #' # When h is missing a hypocycloid is generated
60 | #' ggplot() +
61 | #' geom_epitrochoid(aes(r_max = 4, r_min = 1))
62 | #'
63 | #' ggplot() +
64 | #' geom_epitrochoid(aes(r_max = 8, r_min = 1))
65 | #'
66 | #' ggplot() +
67 | #' geom_epitrochoid(aes(r_max = c(4, 6, 8), r_min = 1))
68 | #'
69 | #' # specifying h
70 | #' ggplot() +
71 | #' geom_epitrochoid(aes(r_max = 4, r_min = 1, h = 4))
72 | #'
73 | #' ggplot() +
74 | #' geom_epitrochoid(aes(r_max = 4, r_min = 3, h = 20 / 13))
75 | #'
76 | #' # Changing the horizontal and vertical scale
77 | #'
78 | #' ggplot() +
79 | #' geom_epitrochoid(aes(r_max = 4, r_min = 3, xscale = 10, yscale = 3))
80 | #'
81 | #' # Rotating shape
82 | #' ggplot() +
83 | #' geom_epitrochoid(aes(r_max = 4, r_min = 3, rotation = pi / 4))
84 | #'
85 | #' # When things go wild
86 | #' ggplot(expand.grid(seq(4, 20, by = 2), c(1, 3, 5, 9))) +
87 | #' geom_epitrochoid(aes(r_max = Var1, r_min = Var2, color = Var1,
88 | #' xscale = Var1 + Var2, yscale = Var1 + Var2)) +
89 | #' coord_fixed() +
90 | #' theme_minimal() +
91 | #' scale_color_viridis_c(option = "B") +
92 | #' guides(color = "none") +
93 | #' facet_wrap(~ Var2)
94 | NULL
95 |
96 | #' @rdname ggshapes-extensions
97 | #' @format NULL
98 | #' @usage NULL
99 | #' @importFrom ggplot2 ggproto Stat aes
100 | #' @export
101 | StatEpitrochoid <- ggproto('StatEpitrochoid', Stat,
102 | compute_layer = function(self, data, params, layout) {
103 |
104 | if (is.null(data)) return(data)
105 | if (is.null(data$x0)) data$x0 <- 0
106 | if (is.null(data$y0)) data$y0 <- 0
107 | if (is.null(data$xscale)) data$xscale <- 1
108 | if (is.null(data$yscale)) data$yscale <- 1
109 | if (is.null(data$h)) data$h <- data$r_min
110 | if (is.null(data$rotation)) data$rotation <- 0
111 | data$group <- seq_len(nrow(data))
112 |
113 | data <- tidyr::nest(data, r_min, r_max, h, x0, y0, xscale, yscale, rotation)
114 | data$data <- lapply(data$data, epitrochoid_calc, params = params)
115 | tidyr::unnest(data)
116 | },
117 | required_aes = c('r_min', 'r_max'),
118 | default_aes = aes(x0 = 0, y0 = 0, h = NULL, xscale = 1, yscale = 1, rotation = 0),
119 | extra_params = c('n_points', 'na.rm')
120 | )
121 |
122 | epitrochoid_calc <- function(data, params) {
123 | t <- seq(from = 0, to = 2 * pi * data$r_min, length.out = params$n_points)
124 |
125 | out <- data.frame(
126 | x = data$x0 + data$xscale * ((data$r_max + data$r_min) * cos(t) -
127 | data$h * cos((data$r_max + data$r_min) / data$r_min * t)) / (data$r_max + data$r_min + data$h),
128 | y = data$y0 + data$yscale * ((data$r_max + data$r_min) * sin(t) -
129 | data$h * sin((data$r_max + data$r_min) / data$r_min * t)) / (data$r_max + data$r_min + data$h)
130 | )
131 |
132 | rotate_df(out, data$rotation)
133 | }
134 |
135 | #' @rdname geom_epitrochoid
136 | #' @importFrom ggplot2 layer
137 | #' @export
138 | stat_epitrochoid <- function(mapping = NULL, data = NULL, geom = "epitrochoid",
139 | position = "identity", n_points = 360, na.rm = FALSE, show.legend = NA,
140 | inherit.aes = TRUE, ...) {
141 | layer(
142 | stat = StatEpitrochoid, data = data, mapping = mapping, geom = geom,
143 | position = position, show.legend = show.legend, inherit.aes = inherit.aes,
144 | params = list(na.rm = na.rm, n_points = n_points, ...)
145 | )
146 | }
147 |
148 | #' @rdname geom_epitrochoid
149 | #' @importFrom ggplot2 layer
150 | #' @export
151 | geom_epitrochoid <- function(mapping = NULL, data = NULL, stat = "epitrochoid",
152 | position = "identity", n_points = 360, na.rm = FALSE,
153 | show.legend = NA, inherit.aes = TRUE, ...) {
154 | layer(data = data, mapping = mapping, stat = stat, geom = GeomShape,
155 | position = position, show.legend = show.legend, inherit.aes = inherit.aes,
156 | params = list(n_points = n_points, na.rm = na.rm, ...))
157 | }
158 |
--------------------------------------------------------------------------------
/R/ggpronto-classes.R:
--------------------------------------------------------------------------------
1 | #' ggshapes extensions to ggplot2
2 | #'
3 | #' ggshapes makes heavy use of the ggproto class system to extend the
4 | #' functionality of ggplot2. In general the actual classes should be of little
5 | #' interest to users as the standard ggplot2 api of using geom_* and stat_*
6 | #' functions for building up the plot is encouraged.
7 | #'
8 | #' @name ggshapes-extensions
9 | #' @rdname ggshapes-extensions
10 | #'
11 | NULL
12 |
--------------------------------------------------------------------------------
/R/lissajous.R:
--------------------------------------------------------------------------------
1 | #' Draw a rose or lissajous curve
2 | #'
3 | #' This geom allows you to draw the lissajous curve.
4 | #'
5 | #' The curve follows the the parameterized form
6 | #'
7 | #' \deqn{x = sin(a\theta + \delta)}
8 | #' \deqn{y = sin(b\theta)}
9 | #'
10 | #' these curves are closed when the radion \eqn{a / b} is rational. delta have
11 | #' been scaled to be in the interval [0, 1].
12 | #'
13 | #' @references \url{https://en.wikipedia.org/wiki/Lissajous_curve}
14 | #' @section Aesthetics:
15 | #' geom_arc understand the following aesthetics (required aesthetics are in
16 | #' bold):
17 | #'
18 | #' - **a**
19 | #' - **b**
20 | #' - **delta**
21 | #' - x0
22 | #' - y0
23 | #' - xscale
24 | #' - yscale
25 | #' - rotation
26 | #' - color
27 | #' - fill
28 | #' - size
29 | #' - linetype
30 | #' - alpha
31 | #' - lineend
32 | #'
33 | #' @section Computed variables:
34 | #'
35 | #' \describe{
36 | #' \item{x, y}{The coordinates for the points along the rose curve}
37 | #' }
38 | #'
39 | #' @inheritParams ggplot2::geom_path
40 | #' @inheritParams ggplot2::stat_identity
41 | #'
42 | #' @param n_points The number of points to sample along the curve.
43 | #'
44 | #' @author Emil Hvitfeldt
45 | #'
46 | #' @name geom_lissajous
47 | #' @rdname geom_lissajous
48 | #'
49 | #' @examples
50 | #' ggplot() +
51 | #' geom_lissajous(aes(a = 5, b = 4, delta = 2))
52 | #'
53 | #' ggplot() +
54 | #' geom_lissajous(aes(a = 2, b = 3, delta = 1))
55 | #'
56 | #' ggplot() +
57 | #' geom_lissajous(aes(a = 1:3, b = 3, delta = 1, x0 = c(1, 4, 7)))
58 | #'
59 | #' # Scaling shapes
60 | #' ggplot() +
61 | #' geom_lissajous(aes(a = 2, b = 3, delta = 1, xscale = 5, yscale = 2))
62 | #'
63 | #' # Rotation shapes
64 | #' ggplot() +
65 | #' geom_lissajous(aes(a = 2, b = 3, delta = 1, rotation = pi / 4))
66 | #'
67 | NULL
68 |
69 | #' @rdname ggshapes-extensions
70 | #' @format NULL
71 | #' @usage NULL
72 | #' @importFrom ggplot2 ggproto Stat aes
73 | #' @export
74 | StatLissajous <- ggproto('StatLissajous', Stat,
75 | compute_layer = function(self, data, params, layout) {
76 | if (is.null(data)) return(data)
77 | if (is.null(data$x0)) data$x0 <- 0
78 | if (is.null(data$y0)) data$y0 <- 0
79 | if (is.null(data$xscale)) data$xscale <- 1
80 | if (is.null(data$yscale)) data$yscale <- 1
81 | if (is.null(data$rotation)) data$rotation <- 0
82 | data$group <- seq_len(nrow(data))
83 |
84 | data <- tidyr::nest(data, a, b, delta, x0, y0, xscale, yscale, rotation)
85 | data$data <- lapply(data$data, lissajous_calc, params = params)
86 | tidyr::unnest(data)
87 | },
88 | required_aes = c('a', 'b', 'delta'),
89 | default_aes = aes(x0 = 0, y0 = 0, xscale = 1, yscale = 1, rotation = 0),
90 | extra_params = c('n_points', 'na.rm')
91 | )
92 |
93 | lissajous_calc <- function(data, params) {
94 | t <- seq(from = 0, to = 2 * pi, length.out = params$n_points)
95 |
96 | out <- data.frame(
97 | x = data$x0 + data$xscale * sin(data$a * t + data$delta * pi),
98 | y = data$y0 + data$yscale * sin(data$b * t)
99 | )
100 |
101 | rotate_df(out, data$rotation)
102 | }
103 |
104 | #' @rdname geom_lissajous
105 | #' @importFrom ggplot2 layer
106 | #' @export
107 | stat_lissajous <- function(mapping = NULL, data = NULL, geom = "lissajous",
108 | position = "identity", n_points = 360, na.rm = FALSE, show.legend = NA,
109 | inherit.aes = TRUE, ...) {
110 | layer(
111 | stat = StatLissajous, data = data, mapping = mapping, geom = geom,
112 | position = position, show.legend = show.legend, inherit.aes = inherit.aes,
113 | params = list(na.rm = na.rm, n_points = n_points, ...)
114 | )
115 | }
116 |
117 | #' @rdname geom_lissajous
118 | #' @importFrom ggplot2 layer
119 | #' @export
120 | geom_lissajous <- function(mapping = NULL, data = NULL, stat = "lissajous",
121 | position = "identity", n_points = 360, na.rm = FALSE,
122 | show.legend = NA, inherit.aes = TRUE, ...) {
123 | layer(data = data, mapping = mapping, stat = stat, geom = GeomShape,
124 | position = position, show.legend = show.legend, inherit.aes = inherit.aes,
125 | params = list(n_points = n_points, na.rm = na.rm, ...))
126 | }
127 |
--------------------------------------------------------------------------------
/R/rose.R:
--------------------------------------------------------------------------------
1 | #' Draw a rose or rhodonea curve
2 | #'
3 | #' This geom allows you to draw mathematical roses. A rose is a sinusoid
4 | #' plotted in polar coordinates.
5 | #'
6 | #' the shape follows the following parameterized form
7 | #'
8 | #' \deqn{x = (cos(k\theta) + c)cos(\theta)}
9 | #' \deqn{y = (cos(k\theta) + c)sin(\theta)}
10 | #'
11 | #' where
12 | #'
13 | #' \deqn{k = n / d}
14 | #'
15 | #' the rose will be a closed loop when k is rational. this can easily be
16 | #' achived by keeping n and d whole numbers. c is the internal offset parameter
17 | #' changing how much the flower spreads out.
18 | #'
19 | #' @references \url{https://en.wikipedia.org/wiki/Rose_(mathematics)}
20 | #' @section Aesthetics:
21 | #' geom_arc understand the following aesthetics (required aesthetics are in
22 | #' bold):
23 | #'
24 | #' - **n**
25 | #' - **d**
26 | #' - **c**
27 | #' - x0
28 | #' - y0
29 | #' - xscale
30 | #' - yscale
31 | #' - rotation
32 | #' - color
33 | #' - fill
34 | #' - size
35 | #' - linetype
36 | #' - alpha
37 | #' - lineend
38 | #'
39 | #' @section Computed variables:
40 | #'
41 | #' \describe{
42 | #' \item{x, y}{The coordinates for the points along the rose curve}
43 | #' }
44 | #'
45 | #' @inheritParams ggplot2::geom_path
46 | #' @inheritParams ggplot2::stat_identity
47 | #'
48 | #' @param n_points The number of points to sample along the curve.
49 | #'
50 | #' @author Emil Hvitfeldt
51 | #'
52 | #' @name geom_rose
53 | #' @rdname geom_rose
54 | #'
55 | #' @examples
56 | #'
57 | #' ggplot() +
58 | #' geom_rose(aes(n = 2, d = 1, c = 0))
59 | #'
60 | #' ggplot() +
61 | #' geom_rose(aes(n = 2, d = 8, c = 0))
62 | #'
63 | #' ggplot() +
64 | #' geom_rose(aes(n = 5, d = 4, c = 4))
65 | #'
66 | #' # Rescaling
67 | #' ggplot() +
68 | #' geom_rose(aes(n = 5, d = 4, c = 4, xscale = 6, yscale = 2))
69 | #'
70 | #' # Rotation
71 | #' ggplot() +
72 | #' geom_rose(aes(n = 2, d = 1, c = 0, rotation = pi / 4))
73 | #'
74 | #' # Multiple roses
75 | #' ggplot() +
76 | #' geom_rose(aes(n = 5:1, d = 1:5, c = 0, x0 = 1:5 * 3))
77 | #'
78 | #' ggplot() +
79 | #' geom_rose(aes(n = 5, d = 4, c = 4), fill = "white")
80 | NULL
81 |
82 | #' @rdname ggshapes-extensions
83 | #' @format NULL
84 | #' @usage NULL
85 | #' @importFrom ggplot2 ggproto Stat aes
86 | #' @export
87 | StatRose <- ggproto('StatRose', Stat,
88 | compute_layer = function(self, data, params, layout) {
89 | if (is.null(data)) return(data)
90 | if (is.null(data$x0)) data$x0 <- 0
91 | if (is.null(data$y0)) data$y0 <- 0
92 | if (is.null(data$xscale)) data$xscale <- 1
93 | if (is.null(data$yscale)) data$yscale <- 1
94 | if (is.null(data$rotation)) data$rotation <- 0
95 | data$group <- seq_len(nrow(data))
96 |
97 | data <- tidyr::nest(data, n, d, c, x0, y0, xscale, yscale, rotation)
98 | data$data <- lapply(data$data, rose_calc, params = params)
99 | tidyr::unnest(data)
100 | },
101 | required_aes = c('n', 'd', 'c'),
102 | default_aes = aes(x0 = 0, y0 = 0, xscale = 1, yscale = 1, rotation = 0),
103 | extra_params = c('n_points', 'na.rm')
104 | )
105 |
106 | rose_calc <- function(data, params) {
107 | k <- data$n / data$d
108 | theta <- seq(from = 0, to = 2 * pi * data$d, length.out = params$n_points)
109 |
110 | out <- data.frame(
111 | x = data$x0 + data$xscale * (cos(k * theta) + data$c) * cos(theta) / (1 + data$c),
112 | y = data$y0 + data$yscale * (cos(k * theta) + data$c) * sin(theta) / (1 + data$c)
113 | )
114 |
115 | rotate_df(out, data$rotation)
116 | }
117 |
118 |
119 | #' @rdname geom_rose
120 | #' @importFrom ggplot2 layer
121 | #' @export
122 | stat_rose <- function(mapping = NULL, data = NULL, geom = "rose",
123 | position = "identity", n_points = 360, na.rm = FALSE,
124 | show.legend = NA, inherit.aes = TRUE, ...) {
125 | layer(
126 | stat = StatRose, data = data, mapping = mapping, geom = geom,
127 | position = position, show.legend = show.legend, inherit.aes = inherit.aes,
128 | params = list(na.rm = na.rm, n_points = n_points, ...)
129 | )
130 | }
131 |
132 | #' @rdname geom_rose
133 | #' @importFrom ggplot2 layer
134 | #' @export
135 | geom_rose <- function(mapping = NULL, data = NULL, stat = "rose",
136 | position = "identity", n_points = 360, na.rm = FALSE,
137 | show.legend = NA, inherit.aes = TRUE, ...) {
138 | layer(data = data, mapping = mapping, stat = stat, geom = GeomShape,
139 | position = position, show.legend = show.legend, inherit.aes = inherit.aes,
140 | params = list(n_points = n_points, na.rm = na.rm, ...))
141 | }
142 |
--------------------------------------------------------------------------------
/R/shape.R:
--------------------------------------------------------------------------------
1 | #' @rdname ggshapes-extensions
2 | #' @format NULL
3 | #' @usage NULL
4 | #' @export
5 | GeomShape <- ggproto('GeomShape', GeomPolygon,
6 | default_aes = list(
7 | colour = 'black',
8 | fill = NA,
9 | size = 0.5,
10 | linetype = 1,
11 | alpha = NA
12 | )
13 | )
14 |
--------------------------------------------------------------------------------
/R/star.R:
--------------------------------------------------------------------------------
1 | #' Draw a n pointed regular star
2 | #'
3 | #' This geom allows you to draw the star curve.
4 | #'
5 | #' @section Aesthetics:
6 | #' geom_arc understand the following aesthetics (required aesthetics are in
7 | #' bold):
8 | #'
9 | #' - **n_tips**
10 | #' - r_min
11 | #' - r_max
12 | #' - offset
13 | #' - x0
14 | #' - y0
15 | #' - xscale
16 | #' - yscale
17 | #' - rotation
18 | #' - color
19 | #' - fill
20 | #' - size
21 | #' - linetype
22 | #' - alpha
23 | #' - lineend
24 | #'
25 | #' @section Computed variables:
26 | #'
27 | #' \describe{
28 | #' \item{x, y}{The coordinates for the points along the star curve}
29 | #' }
30 | #'
31 | #' @inheritParams ggplot2::geom_path
32 | #' @inheritParams ggplot2::stat_identity
33 | #'
34 | #' @param n_points The number of points to sample along the curve.
35 | #'
36 | #' @author Emil Hvitfeldt
37 | #'
38 | #' @name geom_star
39 | #' @rdname geom_star
40 | #'
41 | #' @examples
42 | #' # Changing number of tips
43 | #' ggplot() +
44 | #' geom_star(aes(n_tips = 5))
45 | #'
46 | #' ggplot() +
47 | #' geom_star(aes(n_tips = 11))
48 | #'
49 | #' # changing radei
50 | #' ggplot() +
51 | #' geom_star(aes(r_min = 0.2, r_max = 1, n_tips = 5))
52 | #'
53 | #' ggplot() +
54 | #' geom_star(aes(r_min = 0.7, r_max = 1, n_tips = 5))
55 | #'
56 | #' # rescaling
57 | #' ggplot() +
58 | #' geom_star(aes( n_tips = 5, xscale = 4, yscale = 2))
59 | #'
60 | #' # Rotation
61 | #' ggplot() +
62 | #' geom_star(aes(n_tips = 5, rotation = pi / 4))
63 | #'
64 | #' # Playing witn offset parameter
65 | #' ggplot() +
66 | #' geom_star(aes(n_tips = 5, offset = 0))
67 | #'
68 | #' ggplot() +
69 | #' geom_star(aes(n_tips = 5, offset = 1))
70 | #'
71 | #' ggplot() +
72 | #' geom_star(aes(n_tips = 11, offset = 5))
73 | #'
74 | #' # Multiple stars
75 | #' ggplot() +
76 | #' geom_star(aes(n_tips = c(3, 5, 7),
77 | #' x0 = c(1, 4, 7),
78 | #' y0 = c(1, 4, 7)))
79 | #'
80 | #' # Regular polygons comes up as a special example when
81 | #' # r_max = r_min / cos(pi / n_tips)
82 | #' ggplot() +
83 | #' geom_star(aes(r_min = 0.5, r_max = 0.5 / cos(pi / 5), n_tips = 5))
84 | NULL
85 |
86 | #' @rdname ggshapes-extensions
87 | #' @format NULL
88 | #' @usage NULL
89 | #' @importFrom ggplot2 ggproto Stat aes
90 | #' @export
91 | StatStar <- ggproto('StatStar', Stat,
92 | compute_layer = function(self, data, params, layout) {
93 | if (is.null(data)) return(data)
94 | if (is.null(data$x0)) data$x0 <- 0
95 | if (is.null(data$y0)) data$y0 <- 0
96 | if (is.null(data$xscale)) data$xscale <- 1
97 | if (is.null(data$yscale)) data$yscale <- 1
98 | if (is.null(data$offset)) data$offset <- 0.5
99 | if (is.null(data$r_max)) data$r_max <- 1
100 | if (is.null(data$r_min)) data$r_min <- 0.5
101 | if (is.null(data$rotation)) data$rotation <- 0
102 | data$group <- seq_len(nrow(data))
103 |
104 | data <- tidyr::nest(data, r_min, r_max, n_tips, offset, x0, y0, xscale, yscale, rotation)
105 | data$data <- lapply(data$data, star_calc, params = params)
106 | tidyr::unnest(data)
107 | },
108 | required_aes = c('n_tips'),
109 | default_aes = aes(x0 = 0, y0 = 0, offset = 0.5, xscale = 1, yscale = 1,
110 | r_max = 1, r_min = 0.5, rotation = 0),
111 | extra_params = c('n_points', 'na.rm')
112 | )
113 |
114 | star_calc <- function(data, params) {
115 | theta <- seq(0, 2 * pi, length.out = data$n_tips + 1) + pi / 2
116 | theta_s <-seq(0, 2 * pi, length.out = data$n_tips + 1)[-1] + pi / 2 -
117 | pi / data$n_tips * 2 * data$offset
118 |
119 | out <- data.frame(
120 | x = data$x0 + data$xscale * weave(data$r_max * cos(theta), data$r_min * cos(theta_s)),
121 | y = data$y0 + data$yscale * weave(data$r_max * sin(theta), data$r_min * sin(theta_s))
122 | )
123 |
124 | rotate_df(out, data$rotation)
125 | }
126 |
127 | #' @rdname geom_star
128 | #' @importFrom ggplot2 layer
129 | #' @export
130 | stat_star <- function(mapping = NULL, data = NULL, geom = "star",
131 | position = "identity", n_points = 360, na.rm = FALSE, show.legend = NA,
132 | inherit.aes = TRUE, ...) {
133 | layer(
134 | stat = StatStar, data = data, mapping = mapping, geom = geom,
135 | position = position, show.legend = show.legend, inherit.aes = inherit.aes,
136 | params = list(na.rm = na.rm, n_points = n_points, ...)
137 | )
138 | }
139 |
140 | #' @rdname geom_star
141 | #' @importFrom ggplot2 layer
142 | #' @export
143 | geom_star <- function(mapping = NULL, data = NULL, stat = "star",
144 | position = "identity", n_points = 360, na.rm = FALSE,
145 | show.legend = NA, inherit.aes = TRUE, ...) {
146 | layer(data = data, mapping = mapping, stat = stat, geom = GeomShape,
147 | position = position, show.legend = show.legend, inherit.aes = inherit.aes,
148 | params = list(n_points = n_points, na.rm = na.rm, ...))
149 | }
150 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 |
6 |
7 | ```{r, include = FALSE}
8 | knitr::opts_chunk$set(
9 | collapse = TRUE,
10 | comment = "#>",
11 | fig.path = "man/figures/README-",
12 | out.width = "100%"
13 | )
14 | ```
15 |
16 |
17 | # ggshapes
18 |
19 |
20 | [](https://travis-ci.org/EmilHvitfeldt/ggshapes)
21 |
22 |
23 | The goal of ggshapes is to add more shapes such and stars and other curves to ggplot2 the same way [ggforce](https://github.com/thomasp85/ggforce) adds regular polygons and circles.
24 |
25 | ## Installation
26 |
27 | You can install the released version of ggshapes from [CRAN](https://CRAN.R-project.org) with:
28 |
29 | ``` r
30 | # Not released yet
31 | install.packages("ggshapes")
32 | ```
33 |
34 | And the development version from [GitHub](https://github.com/) with:
35 |
36 | ``` r
37 | # install.packages("devtools")
38 | devtools::install_github("EmilHvitfeldt/ggshapes")
39 | ```
40 |
41 | ## Examples
42 |
43 | ggshapes provides many closed curves, one of which is the simple [rose](https://en.wikipedia.org/wiki/Rose_(mathematics)) curve.
44 |
45 | ```{r example}
46 | library(ggshapes)
47 | ggplot() +
48 | geom_rose(aes(n = 2, d = 1, c = 0))
49 | ```
50 |
51 | Each of these geoms comes with some tuning parameters that result in widely different curves so you should play around.
52 |
53 | ```{r}
54 | data <- data.frame(a = rep(1:6, times = 6),
55 | b = rep(1:6, each = 6),
56 | delta = 1)
57 |
58 | ggplot(data) +
59 | geom_lissajous(aes(a = a, b = b, delta = delta)) +
60 | facet_grid(a ~ b) +
61 | labs(title = "lissajous curves at varying values of a and b", x = "b", y = "a") +
62 | theme_minimal() +
63 | theme(axis.ticks.y = element_blank(),
64 | axis.text.y = element_blank(),
65 | axis.ticks.x = element_blank(),
66 | axis.text.x = element_blank())
67 | ```
68 |
69 | ggshapes doesn't natively work with [gganimate](https://github.com/thomasp85/gganimate) but gifs can be hacked together using [gifski](https://ropensci.org/technotes/2018/07/23/gifski-release/).
70 |
71 | ```{r, eval=FALSE}
72 | library(gifski)
73 | makeplot <- function(){
74 | data <- expand.grid(tips = 2:10, time = seq(0, pi * 2, length.out = 50)[-1])
75 |
76 | datalist <- split(data, data$time)
77 | lapply(datalist, function(data){
78 | p <- ggplot(data) +
79 | geom_star(aes(n_tips = tips, rotation = time)) +
80 | coord_fixed() +
81 | theme_void() +
82 | xlim(-1, 1) +
83 | ylim(-1, 1) +
84 | facet_wrap(~tips)
85 | print(p)
86 | })
87 | }
88 |
89 | gif_file <- save_gif(makeplot(), width = 800, height = 800, res = 200, delay = 0.01, gif_file = "man/example.gif")
90 | ```
91 |
92 | 
93 |
94 | ## Design choices
95 |
96 | All the geoms that produces closed curves (under certain choice of parameters) comes with a couple of geom specifit tuning parameters (`n`, `d` and `c` for `geom_star()`) and some shared aesthetics
97 |
98 | - x0
99 | - y0
100 | - xscale
101 | - yscale
102 | - rotation
103 |
104 | which denote the x and y coordinate of the center, the x and y scaling of the curve and its rotation in radians. By defaults the geoms produces curves bounded between -1 and 1, centered around (0, 0). Rotation is not applied by default. If rotation and scaling is applied then the curve will not be bounded anymore (as it retains its scale).
105 |
106 | ```{r}
107 | ggplot() +
108 | geom_rect(aes(xmin = -1, ymin = -1, xmax = 1, ymax = 1), fill = NA, color = "red", size = 1) +
109 | geom_lissajous(aes(a = 5, b = 4, delta = 2)) +
110 | theme_minimal() +
111 | coord_fixed() +
112 | labs(title = "The curve is bounded by the square going from (-1, -1) to (1, 1)")
113 | ```
114 |
115 | ```{r}
116 | ggplot() +
117 | geom_rect(aes(xmin = -1, ymin = -1, xmax = 1, ymax = 1), fill = NA, color = "red", size = 1) +
118 | geom_lissajous(aes(a = 5, b = 4, delta = 2, rotation = pi / 7)) +
119 | theme_minimal() +
120 | coord_fixed() +
121 | labs(title = "Rotation will leave the curve at the same size")
122 | ```
123 |
124 | ## Inspiration
125 |
126 | The original inspiration for this package came from the post [film flowers](http://bl.ocks.org/sxywu/raw/d612c6c653fb8b4d7ff3d422be164a5d/) by [Shirley Wu](https://twitter.com/sxywu) which drove me to the realization that such visualizations are quite the hassle to do in ggplot2 right now.
127 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # ggshapes
5 |
6 |
7 |
8 | [](https://travis-ci.org/EmilHvitfeldt/ggshapes)
10 |
11 |
12 | The goal of ggshapes is to add more shapes such and stars and other
13 | curves to ggplot2 the same way
14 | [ggforce](https://github.com/thomasp85/ggforce) adds regular polygons
15 | and circles.
16 |
17 | ## Installation
18 |
19 | You can install the released version of ggshapes from
20 | [CRAN](https://CRAN.R-project.org) with:
21 |
22 | ``` r
23 | # Not released yet
24 | install.packages("ggshapes")
25 | ```
26 |
27 | And the development version from [GitHub](https://github.com/) with:
28 |
29 | ``` r
30 | # install.packages("devtools")
31 | devtools::install_github("EmilHvitfeldt/ggshapes")
32 | ```
33 |
34 | ## Examples
35 |
36 | ggshapes provides many closed curves, one of which is the simple
37 | [rose](https://en.wikipedia.org/wiki/Rose_\(mathematics\)) curve.
38 |
39 | ``` r
40 | library(ggshapes)
41 | #> Loading required package: ggplot2
42 | ggplot() +
43 | geom_rose(aes(n = 2, d = 1, c = 0))
44 | ```
45 |
46 |
47 |
48 | Each of these geoms comes with some tuning parameters that result in
49 | widely different curves so you should play around.
50 |
51 | ``` r
52 | data <- data.frame(a = rep(1:6, times = 6),
53 | b = rep(1:6, each = 6),
54 | delta = 1)
55 |
56 | ggplot(data) +
57 | geom_lissajous(aes(a = a, b = b, delta = delta)) +
58 | facet_grid(a ~ b) +
59 | labs(title = "lissajous curves at varying values of a and b", x = "b", y = "a") +
60 | theme_minimal() +
61 | theme(axis.ticks.y = element_blank(),
62 | axis.text.y = element_blank(),
63 | axis.ticks.x = element_blank(),
64 | axis.text.x = element_blank())
65 | ```
66 |
67 |
68 |
69 | ggshapes doesn’t natively work with
70 | [gganimate](https://github.com/thomasp85/gganimate) but gifs can be
71 | hacked together using
72 | [gifski](https://ropensci.org/technotes/2018/07/23/gifski-release/).
73 |
74 | ``` r
75 | library(gifski)
76 | makeplot <- function(){
77 | data <- expand.grid(tips = 2:10, time = seq(0, pi * 2, length.out = 50)[-1])
78 |
79 | datalist <- split(data, data$time)
80 | lapply(datalist, function(data){
81 | p <- ggplot(data) +
82 | geom_star(aes(n_tips = tips, rotation = time)) +
83 | coord_fixed() +
84 | theme_void() +
85 | xlim(-1, 1) +
86 | ylim(-1, 1) +
87 | facet_wrap(~tips)
88 | print(p)
89 | })
90 | }
91 |
92 | gif_file <- save_gif(makeplot(), width = 800, height = 800, res = 200, delay = 0.01, gif_file = "man/example.gif")
93 | ```
94 |
95 | 
96 |
97 | ## Design choices
98 |
99 | All the geoms that produces closed curves (under certain choice of
100 | parameters) comes with a couple of geom specifit tuning parameters (`n`,
101 | `d` and `c` for `geom_star()`) and some shared aesthetics
102 |
103 | - x0
104 | - y0
105 | - xscale
106 | - yscale
107 | - rotation
108 |
109 | which denote the x and y coordinate of the center, the x and y scaling
110 | of the curve and its rotation in radians. By defaults the geoms produces
111 | curves bounded between -1 and 1, centered around (0, 0). Rotation is not
112 | applied by default. If rotation and scaling is applied then the curve
113 | will not be bounded anymore (as it retains its scale).
114 |
115 | ``` r
116 | ggplot() +
117 | geom_rect(aes(xmin = -1, ymin = -1, xmax = 1, ymax = 1), fill = NA, color = "red", size = 1) +
118 | geom_lissajous(aes(a = 5, b = 4, delta = 2)) +
119 | theme_minimal() +
120 | coord_fixed() +
121 | labs(title = "The curve is bounded by the square going from (-1, -1) to (1, 1)")
122 | ```
123 |
124 |
125 |
126 | ``` r
127 | ggplot() +
128 | geom_rect(aes(xmin = -1, ymin = -1, xmax = 1, ymax = 1), fill = NA, color = "red", size = 1) +
129 | geom_lissajous(aes(a = 5, b = 4, delta = 2, rotation = pi / 7)) +
130 | theme_minimal() +
131 | coord_fixed() +
132 | labs(title = "Rotation will leave the curve at the same size")
133 | ```
134 |
135 |
136 |
137 | ## Inspiration
138 |
139 | The original inspiration for this package came from the post [film
140 | flowers](http://bl.ocks.org/sxywu/raw/d612c6c653fb8b4d7ff3d422be164a5d/)
141 | by [Shirley Wu](https://twitter.com/sxywu) which drove me to the
142 | realization that such visualizations are quite the hassle to do in
143 | ggplot2 right now.
144 |
--------------------------------------------------------------------------------
/_pkgdown.yml:
--------------------------------------------------------------------------------
1 | development:
2 | mode: auto
3 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | comment: false
2 |
3 | coverage:
4 | status:
5 | project:
6 | default:
7 | target: auto
8 | threshold: 1%
9 | patch:
10 | default:
11 | target: auto
12 | threshold: 1%
13 |
--------------------------------------------------------------------------------
/cran-comments.md:
--------------------------------------------------------------------------------
1 | ## Test environments
2 |
3 | * local: darwin15.6.0-3.5.2
4 | * travis: 3.1, 3.2, 3.3, oldrel, release, devel
5 | * r-hub: windows-x86_64-devel, ubuntu-gcc-release, fedora-clang-devel
6 | * win-builder: windows-x86_64-devel
7 |
8 | ## R CMD check results
9 |
10 | 0 errors | 0 warnings | 1 note
11 |
12 | * This is a new release.
13 |
--------------------------------------------------------------------------------
/ggshapes.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: No
4 | SaveWorkspace: No
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: Sweave
13 | LaTeX: pdfLaTeX
14 |
15 | AutoAppendNewline: Yes
16 | StripTrailingWhitespace: Yes
17 |
18 | BuildType: Package
19 | PackageUseDevtools: Yes
20 | PackageInstallArgs: --no-multiarch --with-keep.source
21 | PackageRoxygenize: rd,collate,namespace
22 |
--------------------------------------------------------------------------------
/man/example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EmilHvitfeldt/ggshapes/f9cd15572fe7c05b6b408f4f384610725338bd94/man/example.gif
--------------------------------------------------------------------------------
/man/figures/README-example-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EmilHvitfeldt/ggshapes/f9cd15572fe7c05b6b408f4f384610725338bd94/man/figures/README-example-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-2-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EmilHvitfeldt/ggshapes/f9cd15572fe7c05b6b408f4f384610725338bd94/man/figures/README-unnamed-chunk-2-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-3-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EmilHvitfeldt/ggshapes/f9cd15572fe7c05b6b408f4f384610725338bd94/man/figures/README-unnamed-chunk-3-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-4-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EmilHvitfeldt/ggshapes/f9cd15572fe7c05b6b408f4f384610725338bd94/man/figures/README-unnamed-chunk-4-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-5-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EmilHvitfeldt/ggshapes/f9cd15572fe7c05b6b408f4f384610725338bd94/man/figures/README-unnamed-chunk-5-1.png
--------------------------------------------------------------------------------
/man/geom_epitrochoid.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/epitrochoid.R
3 | \name{geom_epitrochoid}
4 | \alias{geom_epitrochoid}
5 | \alias{stat_epitrochoid}
6 | \title{Draw a rose or Epitrochoid curve}
7 | \usage{
8 | stat_epitrochoid(mapping = NULL, data = NULL, geom = "epitrochoid",
9 | position = "identity", n_points = 360, na.rm = FALSE,
10 | show.legend = NA, inherit.aes = TRUE, ...)
11 |
12 | geom_epitrochoid(mapping = NULL, data = NULL, stat = "epitrochoid",
13 | position = "identity", n_points = 360, na.rm = FALSE,
14 | show.legend = NA, inherit.aes = TRUE, ...)
15 | }
16 | \arguments{
17 | \item{mapping}{Set of aesthetic mappings created by \code{\link[=aes]{aes()}} or
18 | \code{\link[=aes_]{aes_()}}. If specified and \code{inherit.aes = TRUE} (the
19 | default), it is combined with the default mapping at the top level of the
20 | plot. You must supply \code{mapping} if there is no plot mapping.}
21 |
22 | \item{data}{The data to be displayed in this layer. There are three
23 | options:
24 |
25 | If \code{NULL}, the default, the data is inherited from the plot
26 | data as specified in the call to \code{\link[=ggplot]{ggplot()}}.
27 |
28 | A \code{data.frame}, or other object, will override the plot
29 | data. All objects will be fortified to produce a data frame. See
30 | \code{\link[=fortify]{fortify()}} for which variables will be created.
31 |
32 | A \code{function} will be called with a single argument,
33 | the plot data. The return value must be a \code{data.frame}, and
34 | will be used as the layer data.}
35 |
36 | \item{geom}{The geometric object to use display the data}
37 |
38 | \item{position}{Position adjustment, either as a string, or the result of
39 | a call to a position adjustment function.}
40 |
41 | \item{n_points}{The number of points to sample along the curve.}
42 |
43 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with
44 | a warning. If \code{TRUE}, missing values are silently removed.}
45 |
46 | \item{show.legend}{logical. Should this layer be included in the legends?
47 | \code{NA}, the default, includes if any aesthetics are mapped.
48 | \code{FALSE} never includes, and \code{TRUE} always includes.
49 | It can also be a named logical vector to finely select the aesthetics to
50 | display.}
51 |
52 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics,
53 | rather than combining with them. This is most useful for helper functions
54 | that define both data and aesthetics and shouldn't inherit behaviour from
55 | the default plot specification, e.g. \code{\link[=borders]{borders()}}.}
56 |
57 | \item{...}{Other arguments passed on to \code{\link[=layer]{layer()}}. These are
58 | often aesthetics, used to set an aesthetic to a fixed value, like
59 | \code{colour = "red"} or \code{size = 3}. They may also be parameters
60 | to the paired geom/stat.}
61 |
62 | \item{stat}{The statistical transformation to use on the data for this
63 | layer, as a string.}
64 | }
65 | \description{
66 | This geom allows you to draw the epitrochoid curve. A epitrochoid is a
67 | curve traced by a point attached to a circle of radius r_min rolling around
68 | the outside of a fixed circle of radius r_max, where the point is at a
69 | distance h from the center of the interior circle. h is the same as r_min
70 | by default.
71 | }
72 | \details{
73 | To unscale the curve, please set xscale and yscale to r_max + r_min + h.
74 |
75 | The curve follows the the parameterized form
76 |
77 | \deqn{x = (r_max + r_min) cos(\theta) - h * cos(\frac{r_max + r_min}{r_min} \theta)}
78 | \deqn{x = (r_max + r_min) sin(\theta) - h * sin(\frac{r_max + r_min}{r_min} \theta)}
79 |
80 | these curves are closed when the radion \eqn{a / b} is rational. delta have
81 | been scaled to be in the interval [0, 1].
82 | }
83 | \section{Aesthetics}{
84 |
85 | geom_arc understand the following aesthetics (required aesthetics are in
86 | bold):
87 |
88 | - **r_max**
89 | - **r_min**
90 | - h
91 | - x0
92 | - y0
93 | - xscale
94 | - yscale
95 | - rotation
96 | - color
97 | - fill
98 | - size
99 | - linetype
100 | - alpha
101 | - lineend
102 | }
103 |
104 | \section{Computed variables}{
105 |
106 |
107 | \describe{
108 | \item{x, y}{The coordinates for the points along the rose curve}
109 | }
110 | }
111 |
112 | \examples{
113 |
114 | # When h is missing a hypocycloid is generated
115 | ggplot() +
116 | geom_epitrochoid(aes(r_max = 4, r_min = 1))
117 |
118 | ggplot() +
119 | geom_epitrochoid(aes(r_max = 8, r_min = 1))
120 |
121 | ggplot() +
122 | geom_epitrochoid(aes(r_max = c(4, 6, 8), r_min = 1))
123 |
124 | # specifying h
125 | ggplot() +
126 | geom_epitrochoid(aes(r_max = 4, r_min = 1, h = 4))
127 |
128 | ggplot() +
129 | geom_epitrochoid(aes(r_max = 4, r_min = 3, h = 20 / 13))
130 |
131 | # Changing the horizontal and vertical scale
132 |
133 | ggplot() +
134 | geom_epitrochoid(aes(r_max = 4, r_min = 3, xscale = 10, yscale = 3))
135 |
136 | # Rotating shape
137 | ggplot() +
138 | geom_epitrochoid(aes(r_max = 4, r_min = 3, rotation = pi / 4))
139 |
140 | # When things go wild
141 | ggplot(expand.grid(seq(4, 20, by = 2), c(1, 3, 5, 9))) +
142 | geom_epitrochoid(aes(r_max = Var1, r_min = Var2, color = Var1,
143 | xscale = Var1 + Var2, yscale = Var1 + Var2)) +
144 | coord_fixed() +
145 | theme_minimal() +
146 | scale_color_viridis_c(option = "B") +
147 | guides(color = "none") +
148 | facet_wrap(~ Var2)
149 | }
150 | \references{
151 | \url{http://mathworld.wolfram.com/Epitrochoid.html}
152 | \url{http://xahlee.info/SpecialPlaneCurves_dir/Epitrochoid_dir/epitrochoid.html}
153 | }
154 | \seealso{
155 | [geom_hypotrochoid()]
156 | }
157 | \author{
158 | Emil Hvitfeldt
159 | }
160 |
--------------------------------------------------------------------------------
/man/geom_hypotrochoid.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/hypotrochoid.R
3 | \name{geom_hypotrochoid}
4 | \alias{geom_hypotrochoid}
5 | \alias{stat_hypotrochoid}
6 | \title{Draw a rose or Hypotrochoid curve}
7 | \usage{
8 | stat_hypotrochoid(mapping = NULL, data = NULL, geom = "hypotrochoid",
9 | position = "identity", n_points = 360, na.rm = FALSE,
10 | show.legend = NA, inherit.aes = TRUE, ...)
11 |
12 | geom_hypotrochoid(mapping = NULL, data = NULL, stat = "hypotrochoid",
13 | position = "identity", n_points = 360, na.rm = FALSE,
14 | show.legend = NA, inherit.aes = TRUE, ...)
15 | }
16 | \arguments{
17 | \item{mapping}{Set of aesthetic mappings created by \code{\link[=aes]{aes()}} or
18 | \code{\link[=aes_]{aes_()}}. If specified and \code{inherit.aes = TRUE} (the
19 | default), it is combined with the default mapping at the top level of the
20 | plot. You must supply \code{mapping} if there is no plot mapping.}
21 |
22 | \item{data}{The data to be displayed in this layer. There are three
23 | options:
24 |
25 | If \code{NULL}, the default, the data is inherited from the plot
26 | data as specified in the call to \code{\link[=ggplot]{ggplot()}}.
27 |
28 | A \code{data.frame}, or other object, will override the plot
29 | data. All objects will be fortified to produce a data frame. See
30 | \code{\link[=fortify]{fortify()}} for which variables will be created.
31 |
32 | A \code{function} will be called with a single argument,
33 | the plot data. The return value must be a \code{data.frame}, and
34 | will be used as the layer data.}
35 |
36 | \item{geom}{The geometric object to use display the data}
37 |
38 | \item{position}{Position adjustment, either as a string, or the result of
39 | a call to a position adjustment function.}
40 |
41 | \item{n_points}{The number of points to sample along the curve.}
42 |
43 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with
44 | a warning. If \code{TRUE}, missing values are silently removed.}
45 |
46 | \item{show.legend}{logical. Should this layer be included in the legends?
47 | \code{NA}, the default, includes if any aesthetics are mapped.
48 | \code{FALSE} never includes, and \code{TRUE} always includes.
49 | It can also be a named logical vector to finely select the aesthetics to
50 | display.}
51 |
52 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics,
53 | rather than combining with them. This is most useful for helper functions
54 | that define both data and aesthetics and shouldn't inherit behaviour from
55 | the default plot specification, e.g. \code{\link[=borders]{borders()}}.}
56 |
57 | \item{...}{Other arguments passed on to \code{\link[=layer]{layer()}}. These are
58 | often aesthetics, used to set an aesthetic to a fixed value, like
59 | \code{colour = "red"} or \code{size = 3}. They may also be parameters
60 | to the paired geom/stat.}
61 |
62 | \item{stat}{The statistical transformation to use on the data for this
63 | layer, as a string.}
64 | }
65 | \description{
66 | This geom allows you to draw the hypotrochoid curve. A hypotrochoid is a
67 | curve traced by a point attached to a circle of radius r_min rolling around
68 | the inside of a fixed circle of radius r_max, where the point is at a
69 | distance h from the center of the interior circle.
70 | }
71 | \details{
72 | To unscale the curve, please set xscale and yscale to abs(r_max - r_min) + h.
73 |
74 | The curve follows the the parameterized form
75 |
76 | \deqn{x = (r_max - r_min) cos(\theta) + h * cos(\frac{r_max - r_min}{r_min} \theta)}
77 | \deqn{x = (r_max - r_min) sin(\theta) + h * sin(\frac{r_max - r_min}{r_min} \theta)}
78 |
79 | these curves are closed when the radion \eqn{a / b} is rational. delta have
80 | been scaled to be in the interval [0, 1].
81 | }
82 | \section{Aesthetics}{
83 |
84 | geom_arc understand the following aesthetics (required aesthetics are in
85 | bold):
86 |
87 | - **r_max**
88 | - **r_min**
89 | - h
90 | - x0
91 | - y0
92 | - xscale
93 | - yscale
94 | - rotation
95 | - color
96 | - fill
97 | - size
98 | - linetype
99 | - alpha
100 | - lineend
101 | }
102 |
103 | \section{Computed variables}{
104 |
105 |
106 | \describe{
107 | \item{x, y}{The coordinates for the points along the rose curve}
108 | }
109 | }
110 |
111 | \examples{
112 |
113 | # When h is missing a hypocycloid is generated
114 | ggplot() +
115 | geom_hypotrochoid(aes(r_max = 4, r_min = 1))
116 |
117 | ggplot() +
118 | geom_hypotrochoid(aes(r_max = 8, r_min = 1))
119 |
120 | ggplot() +
121 | geom_hypotrochoid(aes(r_max = c(4, 6, 8), r_min = 1))
122 |
123 | # specifying h
124 | ggplot() +
125 | geom_hypotrochoid(aes(r_max = 4, r_min = 9, h = 4))
126 |
127 | ggplot() +
128 | geom_hypotrochoid(aes(r_max = 4, r_min = 3, h = 20 / 13))
129 |
130 | # changing rotation
131 | ggplot() +
132 | geom_hypotrochoid(aes(r_max = 4, r_min = 1, rotation = pi / 4))
133 |
134 | # When things go wild
135 | ggplot(expand.grid(seq(4, 20, by = 2), c(1, 3, 5, 9))) +
136 | geom_hypotrochoid(aes(r_max = Var1, r_min = Var2, color = Var1,
137 | xscale = abs(Var1 - Var2) + Var2,
138 | yscale = abs(Var1 - Var2) + Var2)) +
139 | coord_fixed() +
140 | theme_minimal() +
141 | scale_color_viridis_c(option = "B") +
142 | guides(color = "none") +
143 | facet_wrap(~ Var2)
144 | }
145 | \references{
146 | \url{https://en.wikipedia.org/wiki/Hypocycloid}
147 | \url{http://xahlee.info/SpecialPlaneCurves_dir/Hypotrochoid_dir/hypotrochoid.html}
148 | }
149 | \seealso{
150 | [geom_epitrochoid()]
151 | }
152 | \author{
153 | Emil Hvitfeldt
154 | }
155 |
--------------------------------------------------------------------------------
/man/geom_lissajous.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lissajous.R
3 | \name{geom_lissajous}
4 | \alias{geom_lissajous}
5 | \alias{stat_lissajous}
6 | \title{Draw a rose or lissajous curve}
7 | \usage{
8 | stat_lissajous(mapping = NULL, data = NULL, geom = "lissajous",
9 | position = "identity", n_points = 360, na.rm = FALSE,
10 | show.legend = NA, inherit.aes = TRUE, ...)
11 |
12 | geom_lissajous(mapping = NULL, data = NULL, stat = "lissajous",
13 | position = "identity", n_points = 360, na.rm = FALSE,
14 | show.legend = NA, inherit.aes = TRUE, ...)
15 | }
16 | \arguments{
17 | \item{mapping}{Set of aesthetic mappings created by \code{\link[=aes]{aes()}} or
18 | \code{\link[=aes_]{aes_()}}. If specified and \code{inherit.aes = TRUE} (the
19 | default), it is combined with the default mapping at the top level of the
20 | plot. You must supply \code{mapping} if there is no plot mapping.}
21 |
22 | \item{data}{The data to be displayed in this layer. There are three
23 | options:
24 |
25 | If \code{NULL}, the default, the data is inherited from the plot
26 | data as specified in the call to \code{\link[=ggplot]{ggplot()}}.
27 |
28 | A \code{data.frame}, or other object, will override the plot
29 | data. All objects will be fortified to produce a data frame. See
30 | \code{\link[=fortify]{fortify()}} for which variables will be created.
31 |
32 | A \code{function} will be called with a single argument,
33 | the plot data. The return value must be a \code{data.frame}, and
34 | will be used as the layer data.}
35 |
36 | \item{geom}{The geometric object to use display the data}
37 |
38 | \item{position}{Position adjustment, either as a string, or the result of
39 | a call to a position adjustment function.}
40 |
41 | \item{n_points}{The number of points to sample along the curve.}
42 |
43 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with
44 | a warning. If \code{TRUE}, missing values are silently removed.}
45 |
46 | \item{show.legend}{logical. Should this layer be included in the legends?
47 | \code{NA}, the default, includes if any aesthetics are mapped.
48 | \code{FALSE} never includes, and \code{TRUE} always includes.
49 | It can also be a named logical vector to finely select the aesthetics to
50 | display.}
51 |
52 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics,
53 | rather than combining with them. This is most useful for helper functions
54 | that define both data and aesthetics and shouldn't inherit behaviour from
55 | the default plot specification, e.g. \code{\link[=borders]{borders()}}.}
56 |
57 | \item{...}{Other arguments passed on to \code{\link[=layer]{layer()}}. These are
58 | often aesthetics, used to set an aesthetic to a fixed value, like
59 | \code{colour = "red"} or \code{size = 3}. They may also be parameters
60 | to the paired geom/stat.}
61 |
62 | \item{stat}{The statistical transformation to use on the data for this
63 | layer, as a string.}
64 | }
65 | \description{
66 | This geom allows you to draw the lissajous curve.
67 | }
68 | \details{
69 | The curve follows the the parameterized form
70 |
71 | \deqn{x = sin(a\theta + \delta)}
72 | \deqn{y = sin(b\theta)}
73 |
74 | these curves are closed when the radion \eqn{a / b} is rational. delta have
75 | been scaled to be in the interval [0, 1].
76 | }
77 | \section{Aesthetics}{
78 |
79 | geom_arc understand the following aesthetics (required aesthetics are in
80 | bold):
81 |
82 | - **a**
83 | - **b**
84 | - **delta**
85 | - x0
86 | - y0
87 | - xscale
88 | - yscale
89 | - rotation
90 | - color
91 | - fill
92 | - size
93 | - linetype
94 | - alpha
95 | - lineend
96 | }
97 |
98 | \section{Computed variables}{
99 |
100 |
101 | \describe{
102 | \item{x, y}{The coordinates for the points along the rose curve}
103 | }
104 | }
105 |
106 | \examples{
107 | ggplot() +
108 | geom_lissajous(aes(a = 5, b = 4, delta = 2))
109 |
110 | ggplot() +
111 | geom_lissajous(aes(a = 2, b = 3, delta = 1))
112 |
113 | ggplot() +
114 | geom_lissajous(aes(a = 1:3, b = 3, delta = 1, x0 = c(1, 4, 7)))
115 |
116 | # Scaling shapes
117 | ggplot() +
118 | geom_lissajous(aes(a = 2, b = 3, delta = 1, xscale = 5, yscale = 2))
119 |
120 | # Rotation shapes
121 | ggplot() +
122 | geom_lissajous(aes(a = 2, b = 3, delta = 1, rotation = pi / 4))
123 |
124 | }
125 | \references{
126 | \url{https://en.wikipedia.org/wiki/Lissajous_curve}
127 | }
128 | \author{
129 | Emil Hvitfeldt
130 | }
131 |
--------------------------------------------------------------------------------
/man/geom_rose.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/rose.R
3 | \name{geom_rose}
4 | \alias{geom_rose}
5 | \alias{stat_rose}
6 | \title{Draw a rose or rhodonea curve}
7 | \usage{
8 | stat_rose(mapping = NULL, data = NULL, geom = "rose",
9 | position = "identity", n_points = 360, na.rm = FALSE,
10 | show.legend = NA, inherit.aes = TRUE, ...)
11 |
12 | geom_rose(mapping = NULL, data = NULL, stat = "rose",
13 | position = "identity", n_points = 360, na.rm = FALSE,
14 | show.legend = NA, inherit.aes = TRUE, ...)
15 | }
16 | \arguments{
17 | \item{mapping}{Set of aesthetic mappings created by \code{\link[=aes]{aes()}} or
18 | \code{\link[=aes_]{aes_()}}. If specified and \code{inherit.aes = TRUE} (the
19 | default), it is combined with the default mapping at the top level of the
20 | plot. You must supply \code{mapping} if there is no plot mapping.}
21 |
22 | \item{data}{The data to be displayed in this layer. There are three
23 | options:
24 |
25 | If \code{NULL}, the default, the data is inherited from the plot
26 | data as specified in the call to \code{\link[=ggplot]{ggplot()}}.
27 |
28 | A \code{data.frame}, or other object, will override the plot
29 | data. All objects will be fortified to produce a data frame. See
30 | \code{\link[=fortify]{fortify()}} for which variables will be created.
31 |
32 | A \code{function} will be called with a single argument,
33 | the plot data. The return value must be a \code{data.frame}, and
34 | will be used as the layer data.}
35 |
36 | \item{geom}{The geometric object to use display the data}
37 |
38 | \item{position}{Position adjustment, either as a string, or the result of
39 | a call to a position adjustment function.}
40 |
41 | \item{n_points}{The number of points to sample along the curve.}
42 |
43 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with
44 | a warning. If \code{TRUE}, missing values are silently removed.}
45 |
46 | \item{show.legend}{logical. Should this layer be included in the legends?
47 | \code{NA}, the default, includes if any aesthetics are mapped.
48 | \code{FALSE} never includes, and \code{TRUE} always includes.
49 | It can also be a named logical vector to finely select the aesthetics to
50 | display.}
51 |
52 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics,
53 | rather than combining with them. This is most useful for helper functions
54 | that define both data and aesthetics and shouldn't inherit behaviour from
55 | the default plot specification, e.g. \code{\link[=borders]{borders()}}.}
56 |
57 | \item{...}{Other arguments passed on to \code{\link[=layer]{layer()}}. These are
58 | often aesthetics, used to set an aesthetic to a fixed value, like
59 | \code{colour = "red"} or \code{size = 3}. They may also be parameters
60 | to the paired geom/stat.}
61 |
62 | \item{stat}{The statistical transformation to use on the data for this
63 | layer, as a string.}
64 | }
65 | \description{
66 | This geom allows you to draw mathematical roses. A rose is a sinusoid
67 | plotted in polar coordinates.
68 | }
69 | \details{
70 | the shape follows the following parameterized form
71 |
72 | \deqn{x = (cos(k\theta) + c)cos(\theta)}
73 | \deqn{y = (cos(k\theta) + c)sin(\theta)}
74 |
75 | where
76 |
77 | \deqn{k = n / d}
78 |
79 | the rose will be a closed loop when k is rational. this can easily be
80 | achived by keeping n and d whole numbers. c is the internal offset parameter
81 | changing how much the flower spreads out.
82 | }
83 | \section{Aesthetics}{
84 |
85 | geom_arc understand the following aesthetics (required aesthetics are in
86 | bold):
87 |
88 | - **n**
89 | - **d**
90 | - **c**
91 | - x0
92 | - y0
93 | - xscale
94 | - yscale
95 | - rotation
96 | - color
97 | - fill
98 | - size
99 | - linetype
100 | - alpha
101 | - lineend
102 | }
103 |
104 | \section{Computed variables}{
105 |
106 |
107 | \describe{
108 | \item{x, y}{The coordinates for the points along the rose curve}
109 | }
110 | }
111 |
112 | \examples{
113 |
114 | ggplot() +
115 | geom_rose(aes(n = 2, d = 1, c = 0))
116 |
117 | ggplot() +
118 | geom_rose(aes(n = 2, d = 8, c = 0))
119 |
120 | ggplot() +
121 | geom_rose(aes(n = 5, d = 4, c = 4))
122 |
123 | # Rescaling
124 | ggplot() +
125 | geom_rose(aes(n = 5, d = 4, c = 4, xscale = 6, yscale = 2))
126 |
127 | # Rotation
128 | ggplot() +
129 | geom_rose(aes(n = 2, d = 1, c = 0, rotation = pi / 4))
130 |
131 | # Multiple roses
132 | ggplot() +
133 | geom_rose(aes(n = 5:1, d = 1:5, c = 0, x0 = 1:5 * 3))
134 |
135 | ggplot() +
136 | geom_rose(aes(n = 5, d = 4, c = 4), fill = "white")
137 | }
138 | \references{
139 | \url{https://en.wikipedia.org/wiki/Rose_(mathematics)}
140 | }
141 | \author{
142 | Emil Hvitfeldt
143 | }
144 |
--------------------------------------------------------------------------------
/man/geom_star.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/star.R
3 | \name{geom_star}
4 | \alias{geom_star}
5 | \alias{stat_star}
6 | \title{Draw a n pointed regular star}
7 | \usage{
8 | stat_star(mapping = NULL, data = NULL, geom = "star",
9 | position = "identity", n_points = 360, na.rm = FALSE,
10 | show.legend = NA, inherit.aes = TRUE, ...)
11 |
12 | geom_star(mapping = NULL, data = NULL, stat = "star",
13 | position = "identity", n_points = 360, na.rm = FALSE,
14 | show.legend = NA, inherit.aes = TRUE, ...)
15 | }
16 | \arguments{
17 | \item{mapping}{Set of aesthetic mappings created by \code{\link[=aes]{aes()}} or
18 | \code{\link[=aes_]{aes_()}}. If specified and \code{inherit.aes = TRUE} (the
19 | default), it is combined with the default mapping at the top level of the
20 | plot. You must supply \code{mapping} if there is no plot mapping.}
21 |
22 | \item{data}{The data to be displayed in this layer. There are three
23 | options:
24 |
25 | If \code{NULL}, the default, the data is inherited from the plot
26 | data as specified in the call to \code{\link[=ggplot]{ggplot()}}.
27 |
28 | A \code{data.frame}, or other object, will override the plot
29 | data. All objects will be fortified to produce a data frame. See
30 | \code{\link[=fortify]{fortify()}} for which variables will be created.
31 |
32 | A \code{function} will be called with a single argument,
33 | the plot data. The return value must be a \code{data.frame}, and
34 | will be used as the layer data.}
35 |
36 | \item{geom}{The geometric object to use display the data}
37 |
38 | \item{position}{Position adjustment, either as a string, or the result of
39 | a call to a position adjustment function.}
40 |
41 | \item{n_points}{The number of points to sample along the curve.}
42 |
43 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with
44 | a warning. If \code{TRUE}, missing values are silently removed.}
45 |
46 | \item{show.legend}{logical. Should this layer be included in the legends?
47 | \code{NA}, the default, includes if any aesthetics are mapped.
48 | \code{FALSE} never includes, and \code{TRUE} always includes.
49 | It can also be a named logical vector to finely select the aesthetics to
50 | display.}
51 |
52 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics,
53 | rather than combining with them. This is most useful for helper functions
54 | that define both data and aesthetics and shouldn't inherit behaviour from
55 | the default plot specification, e.g. \code{\link[=borders]{borders()}}.}
56 |
57 | \item{...}{Other arguments passed on to \code{\link[=layer]{layer()}}. These are
58 | often aesthetics, used to set an aesthetic to a fixed value, like
59 | \code{colour = "red"} or \code{size = 3}. They may also be parameters
60 | to the paired geom/stat.}
61 |
62 | \item{stat}{The statistical transformation to use on the data for this
63 | layer, as a string.}
64 | }
65 | \description{
66 | This geom allows you to draw the star curve.
67 | }
68 | \section{Aesthetics}{
69 |
70 | geom_arc understand the following aesthetics (required aesthetics are in
71 | bold):
72 |
73 | - **n_tips**
74 | - r_min
75 | - r_max
76 | - offset
77 | - x0
78 | - y0
79 | - xscale
80 | - yscale
81 | - rotation
82 | - color
83 | - fill
84 | - size
85 | - linetype
86 | - alpha
87 | - lineend
88 | }
89 |
90 | \section{Computed variables}{
91 |
92 |
93 | \describe{
94 | \item{x, y}{The coordinates for the points along the star curve}
95 | }
96 | }
97 |
98 | \examples{
99 | # Changing number of tips
100 | ggplot() +
101 | geom_star(aes(n_tips = 5))
102 |
103 | ggplot() +
104 | geom_star(aes(n_tips = 11))
105 |
106 | # changing radei
107 | ggplot() +
108 | geom_star(aes(r_min = 0.2, r_max = 1, n_tips = 5))
109 |
110 | ggplot() +
111 | geom_star(aes(r_min = 0.7, r_max = 1, n_tips = 5))
112 |
113 | # rescaling
114 | ggplot() +
115 | geom_star(aes( n_tips = 5, xscale = 4, yscale = 2))
116 |
117 | # Rotation
118 | ggplot() +
119 | geom_star(aes(n_tips = 5, rotation = pi / 4))
120 |
121 | # Playing witn offset parameter
122 | ggplot() +
123 | geom_star(aes(n_tips = 5, offset = 0))
124 |
125 | ggplot() +
126 | geom_star(aes(n_tips = 5, offset = 1))
127 |
128 | ggplot() +
129 | geom_star(aes(n_tips = 11, offset = 5))
130 |
131 | # Multiple stars
132 | ggplot() +
133 | geom_star(aes(n_tips = c(3, 5, 7),
134 | x0 = c(1, 4, 7),
135 | y0 = c(1, 4, 7)))
136 |
137 | # Regular polygons comes up as a special example when
138 | # r_max = r_min / cos(pi / n_tips)
139 | ggplot() +
140 | geom_star(aes(r_min = 0.5, r_max = 0.5 / cos(pi / 5), n_tips = 5))
141 | }
142 | \author{
143 | Emil Hvitfeldt
144 | }
145 |
--------------------------------------------------------------------------------
/man/ggshapes-extensions.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/epitrochoid.R, R/ggpronto-classes.R,
3 | % R/hypotrochoid.R, R/lissajous.R, R/rose.R, R/shape.R, R/star.R
4 | \docType{data}
5 | \name{StatEpitrochoid}
6 | \alias{StatEpitrochoid}
7 | \alias{ggshapes-extensions}
8 | \alias{StatHypotrochoid}
9 | \alias{StatLissajous}
10 | \alias{StatRose}
11 | \alias{GeomShape}
12 | \alias{StatStar}
13 | \title{ggshapes extensions to ggplot2}
14 | \description{
15 | ggshapes makes heavy use of the ggproto class system to extend the
16 | functionality of ggplot2. In general the actual classes should be of little
17 | interest to users as the standard ggplot2 api of using geom_* and stat_*
18 | functions for building up the plot is encouraged.
19 | }
20 | \keyword{datasets}
21 |
--------------------------------------------------------------------------------
/man/rotate_df.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/aaa.R
3 | \name{rotate_df}
4 | \alias{rotate_df}
5 | \title{Rotates a parametric data.frame}
6 | \usage{
7 | rotate_df(df, theta)
8 | }
9 | \arguments{
10 | \item{df}{a data frame with two columns x and y}
11 |
12 | \item{theta}{a numeric denoting the amount of rotation}
13 | }
14 | \value{
15 | a data frame with two columns x and y
16 | }
17 | \description{
18 | Rotates a parametric data.frame
19 | }
20 |
--------------------------------------------------------------------------------
/man/weave.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/aaa.R
3 | \name{weave}
4 | \alias{weave}
5 | \title{Weaves two vectors together using alternating indecies}
6 | \usage{
7 | weave(a, b)
8 | }
9 | \arguments{
10 | \item{a}{Vector}
11 |
12 | \item{b}{Vector}
13 | }
14 | \value{
15 | A vector
16 | }
17 | \description{
18 | Weaves two vectors together using alternating indecies
19 | }
20 |
--------------------------------------------------------------------------------