11# ' Polar coordinates
22# '
33# ' The polar coordinate system is most commonly used for pie charts, which
4- # ' are a stacked bar chart in polar coordinates.
4+ # ' are a stacked bar chart in polar coordinates. `coord_radial()` has extended
5+ # ' options.
56# '
67# ' @param theta variable to map angle to (`x` or `y`)
78# ' @param start Offset of starting point from 12 o'clock in radians. Offset
@@ -80,12 +81,14 @@ CoordPolar <- ggproto("CoordPolar", Coord,
8081 aspect = function (details ) 1 ,
8182
8283 distance = function (self , x , y , details ) {
84+ arc <- self $ start + c(0 , 2 * pi )
85+ dir <- self $ direction
8386 if (self $ theta == " x" ) {
8487 r <- rescale(y , from = details $ r.range )
85- theta <- theta_rescale_no_clip(self , x , details )
88+ theta <- theta_rescale_no_clip(x , details $ theta.range , arc , dir )
8689 } else {
8790 r <- rescale(x , from = details $ r.range )
88- theta <- theta_rescale_no_clip(self , y , details )
91+ theta <- theta_rescale_no_clip(y , details $ theta.range , arc , dir )
8992 }
9093
9194 dist_polar(r , theta )
@@ -163,10 +166,12 @@ CoordPolar <- ggproto("CoordPolar", Coord,
163166 },
164167
165168 transform = function (self , data , panel_params ) {
169+ arc <- self $ start + c(0 , 2 * pi )
170+ dir <- self $ direction
166171 data <- rename_data(self , data )
167172
168- data $ r <- r_rescale(self , data $ r , panel_params $ r.range )
169- data $ theta <- theta_rescale(self , data $ theta , panel_params )
173+ data $ r <- r_rescale(data $ r , panel_params $ r.range )
174+ data $ theta <- theta_rescale(data $ theta , panel_params $ theta.range , arc , dir )
170175 data $ x <- data $ r * sin(data $ theta ) + 0.5
171176 data $ y <- data $ r * cos(data $ theta ) + 0.5
172177
@@ -176,11 +181,10 @@ CoordPolar <- ggproto("CoordPolar", Coord,
176181 render_axis_v = function (self , panel_params , theme ) {
177182 arrange <- panel_params $ r.arrange %|| % c(" primary" , " secondary" )
178183
179- x <- r_rescale(self , panel_params $ r.major , panel_params $ r.range ) + 0.5
184+ x <- r_rescale(panel_params $ r.major , panel_params $ r.range ) + 0.5
180185 panel_params $ r.major <- x
181186 if (! is.null(panel_params $ r.sec.major )) {
182187 panel_params $ r.sec.major <- r_rescale(
183- self ,
184188 panel_params $ r.sec.major ,
185189 panel_params $ r.sec.range
186190 ) + 0.5
@@ -201,14 +205,16 @@ CoordPolar <- ggproto("CoordPolar", Coord,
201205
202206 render_bg = function (self , panel_params , theme ) {
203207 panel_params <- rename_data(self , panel_params )
208+ arc <- self $ start + c(0 , 2 * pi )
209+ dir <- self $ direction
204210
205211 theta <- if (length(panel_params $ theta.major ) > 0 )
206- theta_rescale(self , panel_params $ theta.major , panel_params )
212+ theta_rescale(panel_params $ theta.major , panel_params $ theta.range , arc , dir )
207213 thetamin <- if (length(panel_params $ theta.minor ) > 0 )
208- theta_rescale(self , panel_params $ theta.minor , panel_params )
214+ theta_rescale(panel_params $ theta.minor , panel_params $ theta.range , arc , dir )
209215 thetafine <- seq(0 , 2 * pi , length.out = 100 )
210216
211- rfine <- c(r_rescale(self , panel_params $ r.major , panel_params $ r.range ), 0.45 )
217+ rfine <- c(r_rescale(panel_params $ r.major , panel_params $ r.range ), 0.45 )
212218
213219 # This gets the proper theme element for theta and r grid lines:
214220 # panel.grid.major.x or .y
@@ -247,8 +253,10 @@ CoordPolar <- ggproto("CoordPolar", Coord,
247253 if (is.null(panel_params $ theta.major )) {
248254 return (element_render(theme , " panel.border" ))
249255 }
256+ arc <- self $ start + c(0 , 2 * pi )
257+ dir <- self $ direction
250258
251- theta <- theta_rescale(self , panel_params $ theta.major , panel_params )
259+ theta <- theta_rescale(panel_params $ theta.major , panel_params $ theta.range , arc , dir )
252260 labels <- panel_params $ theta.labels
253261
254262 # Combine the two ends of the scale if they are close
@@ -305,18 +313,16 @@ rename_data <- function(coord, data) {
305313 }
306314}
307315
308- theta_rescale_no_clip <- function (coord , x , panel_params ) {
309- rotate <- function (x ) (x + coord $ start ) * coord $ direction
310- rotate(rescale(x , c(0 , 2 * pi ), panel_params $ theta.range ))
316+ theta_rescale_no_clip <- function (x , range , arc = c(0 , 2 * pi ), direction = 1 ) {
317+ rescale(x , to = arc , from = range ) * direction
311318}
312319
313- theta_rescale <- function (coord , x , panel_params ) {
314- x <- squish_infinite(x , panel_params $ theta.range )
315- rotate <- function (x ) (x + coord $ start ) %% (2 * pi ) * coord $ direction
316- rotate(rescale(x , c(0 , 2 * pi ), panel_params $ theta.range ))
320+ theta_rescale <- function (x , range , arc = c(0 , 2 * pi ), direction = 1 ) {
321+ x <- squish_infinite(x , range )
322+ rescale(x , to = arc , from = range ) %% (2 * pi ) * direction
317323}
318324
319- r_rescale <- function (coord , x , range ) {
325+ r_rescale <- function (x , range , donut = c( 0 , 0.4 ) ) {
320326 x <- squish_infinite(x , range )
321- rescale(x , c( 0 , 0.4 ) , range )
327+ rescale(x , donut , range )
322328}
0 commit comments