1
1
# ' Polar coordinates
2
2
# '
3
3
# ' 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.
5
6
# '
6
7
# ' @param theta variable to map angle to (`x` or `y`)
7
8
# ' @param start Offset of starting point from 12 o'clock in radians. Offset
@@ -80,12 +81,14 @@ CoordPolar <- ggproto("CoordPolar", Coord,
80
81
aspect = function (details ) 1 ,
81
82
82
83
distance = function (self , x , y , details ) {
84
+ arc <- self $ start + c(0 , 2 * pi )
85
+ dir <- self $ direction
83
86
if (self $ theta == " x" ) {
84
87
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 )
86
89
} else {
87
90
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 )
89
92
}
90
93
91
94
dist_polar(r , theta )
@@ -163,10 +166,12 @@ CoordPolar <- ggproto("CoordPolar", Coord,
163
166
},
164
167
165
168
transform = function (self , data , panel_params ) {
169
+ arc <- self $ start + c(0 , 2 * pi )
170
+ dir <- self $ direction
166
171
data <- rename_data(self , data )
167
172
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 )
170
175
data $ x <- data $ r * sin(data $ theta ) + 0.5
171
176
data $ y <- data $ r * cos(data $ theta ) + 0.5
172
177
@@ -176,11 +181,10 @@ CoordPolar <- ggproto("CoordPolar", Coord,
176
181
render_axis_v = function (self , panel_params , theme ) {
177
182
arrange <- panel_params $ r.arrange %|| % c(" primary" , " secondary" )
178
183
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
180
185
panel_params $ r.major <- x
181
186
if (! is.null(panel_params $ r.sec.major )) {
182
187
panel_params $ r.sec.major <- r_rescale(
183
- self ,
184
188
panel_params $ r.sec.major ,
185
189
panel_params $ r.sec.range
186
190
) + 0.5
@@ -201,14 +205,16 @@ CoordPolar <- ggproto("CoordPolar", Coord,
201
205
202
206
render_bg = function (self , panel_params , theme ) {
203
207
panel_params <- rename_data(self , panel_params )
208
+ arc <- self $ start + c(0 , 2 * pi )
209
+ dir <- self $ direction
204
210
205
211
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 )
207
213
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 )
209
215
thetafine <- seq(0 , 2 * pi , length.out = 100 )
210
216
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 )
212
218
213
219
# This gets the proper theme element for theta and r grid lines:
214
220
# panel.grid.major.x or .y
@@ -247,8 +253,10 @@ CoordPolar <- ggproto("CoordPolar", Coord,
247
253
if (is.null(panel_params $ theta.major )) {
248
254
return (element_render(theme , " panel.border" ))
249
255
}
256
+ arc <- self $ start + c(0 , 2 * pi )
257
+ dir <- self $ direction
250
258
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 )
252
260
labels <- panel_params $ theta.labels
253
261
254
262
# Combine the two ends of the scale if they are close
@@ -305,18 +313,16 @@ rename_data <- function(coord, data) {
305
313
}
306
314
}
307
315
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
311
318
}
312
319
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
317
323
}
318
324
319
- r_rescale <- function (coord , x , range ) {
325
+ r_rescale <- function (x , range , donut = c( 0 , 0.4 ) ) {
320
326
x <- squish_infinite(x , range )
321
- rescale(x , c( 0 , 0.4 ) , range )
327
+ rescale(x , donut , range )
322
328
}
0 commit comments