Volleyball court schematic suitable for adding to a ggplot
Usage
ggcourt(
court = "full",
show_zones = TRUE,
labels = c("Serving team", "Receiving team"),
as_for_serve = FALSE,
show_zone_lines = TRUE,
show_minor_zones = FALSE,
show_3m_line = TRUE,
grid_colour = "black",
zone_colour = "grey70",
minor_zone_colour = "grey80",
fixed_aspect_ratio = TRUE,
zone_font_size = 10,
label_font_size = 12,
label_colour = "black",
court_colour = NULL,
figure_colour = NULL,
background_only = FALSE,
foreground_only = FALSE,
line_width = 0.5,
xlim,
ylim,
...
)
Arguments
- court
string: "full" (show full court) or "lower" or "upper" (show only the lower or upper half of the court)
- show_zones
logical: add numbers indicating the court zones (3m squares)?
- labels
string: labels for the lower and upper court halves (pass NULL for no labels)
- as_for_serve
logical: if TRUE and
show_zones
is TRUE, show zones as for serving. Only zones 1,5,6,7,9 are meaningful in this case- show_zone_lines
logical: if FALSE, just show the 3m line. If TRUE, also show the 3m x 3m zones
- show_minor_zones
logical: add lines for the subzones (1.5m squares)?
- show_3m_line
logical: if TRUE, show the 3m (10ft) line
- grid_colour
string: colour to use for court sidelines, 3m line, and net
- zone_colour
string: colour to use for zone lines and labels
- minor_zone_colour
string: colour to use for minor zone grid lines
- fixed_aspect_ratio
logical: if TRUE, coerce the plotted court to be square (for a half-court plot) or a 2:1 rectangle (full court plot). Prior to package version 0.5.3 this was not TRUE by default
- zone_font_size
numeric: the font size of the zone labels
- label_font_size
numeric: the font size of the labels
- label_colour
string: colour to use for labels
- court_colour
string: colour to use for the court. If
NULL
, the court is only plotted with lines (no colour fill) and so thefigure_colour
will show through. Several special values are also supported here:court_colour = "indoor"
can be used as a shortcut to set the court colour to orange, figure colour to blue, and lines and labels to white (similar to the typical indoor court colour scheme)court_colour = "beach"
can be used as a shortcut to set the court and figure colour to a sandy-coloured yellow, lines and labels to black, and with the 3m line not shown by defaultcourt_colour = "sand"
as for "beach" but with a sand texture image used as the court background
- figure_colour
string: colour to set the figure background to. If
NULL
, the background colour of the theme will be used (white, by default)- background_only
logical: if
TRUE
, only plot the background elements (including general plot attributes such as the theme)- foreground_only
logical: if
TRUE
, only plot the foreground elements (grid lines, labels, etc)- line_width
numeric: line width (passed as the size parameter to e.g.
ggplot2::geom_path
)- xlim
numeric: (optional) limits for the x-axis
- ylim
numeric: (optional) limits for the y-axis
- ...
: additional parameters passed to
ggplot2::theme_classic
Details
The datavolley package uses the following dimensions and coordinates for plotting:
the court is shown such that the sidelines are oriented vertically and the net is oriented horizontally
the intersection of the left-hand sideline and the bottom baseline is at (0.5, 0.5)
the intersection of the right-hand sideline and the top baseline is at (3.5, 6.5)
the net intersects the sidelines at (0.5, 3.5) and (3.5, 3.5)
the zones 1-9 (as defined in the DataVolley manual) on the lower half of the court are located at:
(3, 1)
(3, 3)
(2, 3)
(1, 3)
(1, 1)
(2, 1)
(1, 2)
(2, 2)
(3, 2)
the zones 1-9 (as defined in the DataVolley manual) on the upper half of the court are located at:
(1, 6)
(1, 4)
(2, 4)
(3, 4)
(3, 6)
(2, 6)
(3, 5)
(2, 5)
(1, 5)
To get a visual depiction of this, try: ggplot() + ggcourt() + theme_bw()
Examples
if (FALSE) {
x <- dv_read(dv_example_file(), insert_technical_timeouts=FALSE)
library(ggplot2)
library(dplyr)
## Example 1: attack frequency by zone, per team
attack_rate <- plays(x) %>% dplyr::filter(skill == "Attack") %>%
group_by(team, start_zone) %>% dplyr::summarize(n_attacks=n()) %>%
mutate(rate=n_attacks/sum(n_attacks)) %>% ungroup
## add columns "x" and "y" for the x,y coordinates associated with the zones
attack_rate <- cbind(attack_rate, dv_xy(attack_rate$start_zone, end = "lower"))
## for team 2, these need to be on the top half of the diagram
tm2 <- attack_rate$team == teams(x)[2]
attack_rate[tm2, c("x", "y")] <- dv_xy(attack_rate$start_zone, end = "upper")[tm2, ]
## plot this
ggplot(attack_rate, aes(x, y, fill = rate)) + geom_tile() + ggcourt(labels = teams(x)) +
scale_fill_gradient2(name = "Attack rate")
## Example 2: controlling layering
## use the background_only and foreground_only parameters to control the
## order of layers in a plot
ggplot(attack_rate, aes(x, y, fill=rate)) +
## add the background court colours
ggcourt(court_colour = "indoor", background_only = TRUE) +
## now the heatmap
geom_tile() +
## and finally the grid lines and labels
ggcourt(labels = teams(x), foreground_only = TRUE, court_colour = "indoor")
## Example 3: map of starting and ending zones of attacks using arrows
## first tabulate attacks by starting and ending zone
attack_rate <- plays(x) %>% dplyr::filter(team == teams(x)[1] & skill == "Attack") %>%
group_by(start_zone, end_zone) %>% tally() %>% ungroup
## convert counts to rates
attack_rate$rate <- attack_rate$n/sum(attack_rate$n)
## discard zones with zero attacks or missing location information
attack_rate <- attack_rate %>% dplyr::filter(rate>0 & !is.na(start_zone) & !is.na(end_zone))
## add starting x,y coordinates
attack_rate <- cbind(attack_rate, dv_xy(attack_rate$start_zone, end = "lower",
xynames = c("sx","sy")))
## and ending x,y coordinates
attack_rate <- cbind(attack_rate, dv_xy(attack_rate$end_zone, end = "upper",
xynames = c("ex","ey")))
## plot in reverse order so largest arrows are on the bottom
attack_rate <- attack_rate %>% dplyr::arrange(desc(rate))
p <- ggplot(attack_rate, aes(x, y, col = rate)) + ggcourt(labels = c(teams(x)[1], ""))
for (n in 1:nrow(attack_rate))
p <- p + geom_path(data = data.frame(x = c(attack_rate$sx[n], attack_rate$ex[n]),
y = c(attack_rate$sy[n], attack_rate$ey[n]),
rate = attack_rate$rate[n]),
aes(size = rate), lineend = "round",
arrow = arrow(length = unit(2, "mm"), type = "closed",
angle = 20, ends = "last"))
p + scale_colour_gradient(name = "Attack rate") + guides(size = "none")
}