pretty_axis | R Documentation |
This function is used to define pretty limits and axes on plots. The function can handle numeric, time stamp (i.e. Dates
or DateTimeClasses
) or factor data. Usually, arguments are passed from a plotting function (e.g., pretty_plot
) to this function via pretty_axis_args
, although it can be called directly too. In the latter case, generally, the best approach is to implement the function prior to creating a plot. Based on the data to be plotted, the function defines axes limits and corresponding 'pretty' axis tick marks and labels, returning a list of outputs. Then, a plot can be created using limits defined by the function, after which point axes can be added to the plot by passing the list back to the function. Axis limits, placement, the number of ticks, labels and other axes properties can be determined automatically (in which case the function tries hard to create 'pretty' axes), adjusted (e.g. via adjustments to the number of 'pretty' breaks) or user-defined (e.g. by specifying axis breaks). Each axis can be controlled independently (e.g., one axis can be user-defined while another axis can be determined automatically and the function defines appropriate limits and axis placement). The function is very flexible (see Examples).
pretty_axis(
side = 1:4,
x = list(),
lim = list(),
pretty = list(n = 5),
units = list(),
axis = list(),
pi_notation = NULL,
control_axis = list(las = TRUE),
control_sci_notation = list(),
control_digits = NULL,
control_factor_lim = 0.5,
axis_ls = NULL,
add = FALSE,
return_list = TRUE,
...
)
side |
A numeric input specifying the side(s) of a plot for which pretty axes should be defined. |
x |
A list, with one element for each side, defining the values to be plotted on that side of the plot. Numeric, time stamp (i.e. |
lim |
(optional) A list, with one element for each side, containing a vector of (one or both) axes limits for that axis. If provided, then axis tick marks (pretty or regular) are forced to lie within provided limits. Otherwise, suitable limits can be suggested by the function based on the data provided in |
pretty |
A named list arguments that are used to create pretty axis tick marks. This list is passed to |
units |
(optional) A list of units for each side. If |
axis |
(optional) A named list of arguments that are supplied to |
pi_notation |
(optional) A named list of arguments, passed to |
control_axis |
(optional) A named list of arguments that affect all axes. This is only useful if a nested list is provided to |
control_sci_notation |
A named list of arguments that controls scientific notation (see |
control_digits |
(optional) An integer which defines the number of decimal places on numeric axes. If |
control_factor_lim |
(optional) A number which specifies an additive adjustment to limits for a factor axis. For factors, with one or more level, limits become (0.75 - |
axis_ls |
(optional) The output of a call to |
add |
A logical input specifying whether or not to plot the axes. Usually, prettier plots result when |
return_list |
(depreciated) A logical input defining whether or not to return a list of axis parameters defined by the function. |
... |
Arguments ( |
The function returns a list of parameters with an element for each side
. Each element is a list which contains two elements: 'lim', a vector of the lower and upper axis limits for that side
and 'axis', a list of parameters that define the axis for that side
.
Edward Lavender
#### Generate some data for numeric examples
set.seed(1)
x <- 1:10
y <- rnorm(length(x), x*5-10, 5)
#### The default options
# The default options define the parameters of pretty axes with approx. n = 5 breaks
# apply pretty_axis to generate a list of parameters for pretty axes;
# we'll use the outputs to set the limits of the graph and then add pretty axes:
axis_args <-
pretty_axis(side = 1:2,
x = list(x, y),
pretty = list(n = 5),
add = FALSE,
return_list = TRUE
)
# plot the graph using limits defined by function
plot(x, y, axes = FALSE, xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim)
# add pretty axes by passing the axis_args list back to the function
pretty_axis(axis_ls = axis_args, add = TRUE)
#### Adjusting pretty axes via the pretty argument
# We can add arguments to the pretty list that are passed to pretty() or lubridate::pretty_dates()
# ... to adjust the pretty axes produced.
# ... For example, we can adjust the minimum number of intervals on all axes if required:
axis_args <-
pretty_axis(side = 1:2,
x = list(x, y),
pretty = list(n = 5, min.n = 5),
add = FALSE,
return_list = TRUE
)
plot(x, y, axes = FALSE, xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim)
pretty_axis(axis_ls = axis_args, add = TRUE)
#### Adjusting different axes differently
# In example 1 and 2, the changes to the pretty argument affect all axes
# ... added to all specified sides. To make changes side-specific,
# ... we need to specify the arguments for each side in a separate list.
# For example, to have approx. 5 breaks on the first axis and 20 breaks on the second:
axis_args <-
pretty_axis(side = 1:2,
x = list(x, y),
pretty = list(list(n = 5), list(n = 20)),
add = FALSE,
return_list = TRUE
)
plot(x, y, axes = FALSE, xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim)
pretty_axis(axis_ls = axis_args, add = TRUE)
#### Pretty labels can be constrained within limits:
# Pretty labels are forced to be within limits if these are specified by the user
axis_args <-
pretty_axis(side = 1:2,
x = list(x, y),
lim = list(x = c(-3, 15), y = c(-19, 49)),
pretty = list(n = 5),
add = FALSE,
return_list = TRUE
)
plot(x, y, axes = FALSE, xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim)
pretty_axis(axis_ls = axis_args, add = TRUE)
# Axes limits can be specified for some axes but not others by suppling
# ... NULL elements to the lim list, as follows:
axis_args <-
pretty_axis(side = 1:2,
x = list(x, y),
lim = list(NULL, c(-19, 49)),
pretty = list(n = 5),
add = FALSE,
return_list = TRUE
)
plot(x, y, axes = FALSE, xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim)
pretty_axis(axis_ls = axis_args, add = TRUE)
#### For any axis, only one limit can be fixed and the other will be define internally:
# If only one limit is provided, this is assumed to be the first limit:
pretty_axis(side = 1:2, x = list(x, y), lim = list(0, NULL))[[1]]$lim
# The second limit can be coded explicitly as NA:
pretty_axis(side = 1:2, x = list(x, y), lim = list(c(0, NA), NULL))[[1]]$lim
# To hard-code the second limit, you must specify the first limit as NA:
pretty_axis(side = 1:2, x = list(x, y), lim = list(c(0, NA), NULL))[[1]]$lim
# Times work in the same way (see also later exampes):
pretty_axis(side = 1:2,
x = list(as.Date(c("2016-01-04", "2016-05-01")), 1:2),
lim = list(as.Date("2016-01-01"), NULL))[[1]]$lim
pretty_axis(side = 1:2,
x = list(as.POSIXct(c("2016-01-04", "2016-05-01")), 1:2),
lim = list(as.POSIXct("2016-01-01"), NULL))[[1]]$lim
#### We can create regular sequences instead of pretty ones
# Instead of creating 'pretty' axes, we can choose to create a regular sequence
# ... and specify the total number of units between the start and end points
# ... (if we don't specify this, the default is 5 units or
# ... an automatically determined number of time steps, see below).
# Note that because units only takes one argument for each axes,
# ... we do not specify a nested list like we do for the pretty argument
# ... (or, as we'll see below) for the axis argument,
# ... in which all the arguments for each side need to be grouped into a list.
axis_args <-
pretty_axis(side = 1:2,
x = list(x, y),
lim = list(x = c(-2, 12), y = c(-10, 41)),
units = list(5, 3),
add = FALSE,
return_list = TRUE
)
plot(x, y, axes = FALSE, xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim)
pretty_axis(axis_ls = axis_args, add = TRUE)
#### More on controlling each axis separately
# Of course, we can have some axes with pretty axes and others with user defined units
axis_args <-
pretty_axis(side = 1:2,
x = list(x, y),
lim = list(x = c(-2, 12), y = c(-10, 41)),
pretty = list(list(), list(n = 5)),
units = list(5, NULL),
axis_ls = NULL,
add = FALSE,
return_list = TRUE
)
plot(x, y, axes = FALSE, xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim)
pretty_axis(axis_ls = axis_args, add = TRUE)
#### Arguments are passed to axis(), axis.POSIXct() or axis.Date() via the axis argument
# As above, if we supply these once they will affect all graphs:
axis_args <-
pretty_axis(side = 1:2,
x = list(x, y),
lim = list(x = c(-2, 12), y = c(-10, 41)),
pretty = list(list(), list(n = 5)),
units = list(5, NULL),
axis = list(col = "red", cex.axis = 1.5),
axis_ls = NULL,
add = FALSE,
return_list = TRUE
)
plot(x, y, axes = FALSE, xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim)
pretty_axis(axis_ls = axis_args, add = TRUE)
#### Graphical properties of each axis can be controlled separately
# We can change individual axes by creating a list of arguments for each axis
# changes to individual axes need to be specified via individual lists;
# e.g. to make the first axis red and the second blue, and to have 10 pretty labels
# ... on the first axis and 5 on the second we need to:
axis_args <-
pretty_axis(side = 1:2,
x = list(x, y),
lim = list(x = c(-2, 12), y = c(-10, 41)),
pretty = list(list(n = 10), list(n = 5)),
units = list(),
axis = list(list(col = "blue", cex.axis = 1.5), list(col = "red", cex.axis = 1.5)),
axis_ls = NULL,
add = FALSE,
return_list = TRUE
)
plot(x, y, axes = FALSE, xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim)
pretty_axis(axis_ls = axis_args, add = TRUE)
#### Shared arguments for each axis (e.g., cex.axis) can be passed via control_axis
# ... list to reduce typing in cases where other axis parameters require separate control
# ... (i.e., to avoid having to pass these arguments to every list in a nested list).
axis_args <-
pretty_axis(side = 1:2,
x = list(x, y),
lim = list(x = c(-2, 12), y = c(-10, 41)),
pretty = list(list(n = 10), list(n = 5)),
units = list(),
axis = list(list(col = "blue"), list(col = "red")),
control_axis = list(cex.axis = 1.5),
axis_ls = NULL,
add = FALSE,
return_list = TRUE
)
axis_args[[1]]$axis$cex.axis
axis_args[[2]]$axis$cex.axis
#### Control the number of decimal places for numeric axes via control_digits
# axis label decimal places are chosen automatically with the default setting control_digits = NULL:
axis_ls <- pretty_axis(side = 1, x = list(seq(0, 1, by = 0.1)), control_digits = 1)
axis_ls[[1]]$axis$labels
# user-specified decimal places:
axis_ls <- pretty_axis(side = 1, x = list(seq(0, 1, by = 0.1)), control_digits = 3)
axis_ls[[1]]$axis$labels
#### Generate time stamp data
# Generate some x and y values, where x values are time stamps
# ... in POSIXct format. Note the incorporation of tz.
x <- seq.POSIXt(as.POSIXct("2016-01-01", tz = "UTC"),
as.POSIXct("2016-01-02", tz = "UTC"), by = "2 mins")
y <- rnorm(length(x), as.numeric(x)*1e-6 + 100, 50)
#### We can use this function with time stamps in POSIXct format too.
# Apply pretty_axis() function prior to plot to obtain suitable limits:
axis_args <-
pretty_axis(side = 1:4,
x = list(x, y),
lim = list(),
pretty = list(n = 5),
axis = list(list(),
list(las = TRUE),
list(labels = FALSE),
list(labels = FALSE)),
axis_ls = NULL,
add = FALSE,
return_list = TRUE
)
# Plot graph using pretty_axis() limits:
plot(x, y,
type = "l",
axes = FALSE,
xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim
)
# Add pretty axes by passing the list of axis_args back to the function
pretty_axis(axis_ls = axis_args, add = TRUE)
#### Axis parameters for time stamps are passed to axis.POSIXct() or axis.Date()
# ... which can incorporate other options
axis_args <-
pretty_axis(side = 1:4,
x = list(x, y),
lim = list(),
pretty = list(n = 5),
axis = list(list(format = "%H"),
list(las = TRUE),
list(labels = FALSE),
list(labels = FALSE)),
axis_ls = NULL,
add = FALSE,
return_list = TRUE
)
plot(x, y,
type = "l",
axes = FALSE,
xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim)
pretty_axis(axis_ls = axis_args, add = TRUE)
#### Regular sequences, instead of 'pretty' axes can be generated with dates too
# To do this, units takes a character input (e.g. "mins" or "hours")
axis_args <-
pretty_axis(side = 1:4,
x = list(x, y),
lim = list(),
pretty = list(list(), list(n = 3)),
units = list("hours", NULL),
axis = list(list(format = "%H"),
list(las = TRUE),
list(labels = FALSE),
list(labels = FALSE)),
axis_ls = NULL,
add = FALSE,
return_list = TRUE
)
plot(x, y,
type = "l",
axes = FALSE,
xlim = axis_args$`1`$lim, ylim = axis_args$`2`$lim)
pretty_axis(axis_ls = axis_args, add = TRUE)
#### For factors, pretty axes can be created via pretty or via units.
# .. If pretty is supplied, approximately n factor levels are retained:
# ... and corresponding labels are added by default.
# Example data:
dx <- factor(LETTERS[1:10])
dy <- 1:10
# Example with tick for every level:
axis_ls <-
pretty_axis(side = 1:2,
x = list(dx, dy),
pretty = list(n = length(dx)),
add = FALSE,
return_list = TRUE
)
axis_ls[[1]]
# Note that x limits are automatically defined between 1 and the maximum number of factors:
axis_ls[[1]]; length(levels(dx))
# However, default factor limits can be extended via control_factor_lim
axis_ls <-
pretty_axis(side = 1:2,
x = list(dx, dy),
pretty = list(n = length(dx)),
control_factor_lim = 0.5,
add = FALSE,
return_list = TRUE
)
axis_ls[[1]]$lim
# Example with tick mark for every other level
axis_ls <-
pretty_axis(side = 1:2,
x = list(dx, dy),
pretty = list(n = length(dx)/2),
add = FALSE,
return_list = TRUE
)
axis_ls[[1]]
#### For factors, pretty axes can also be specified via units:
# For example, to select every factor level:
axis_ls <-
pretty_axis(side = 1:2,
x = list(dx, dy),
pretty = list(list(), list(n = 5)),
units = list(1, NULL),
add = FALSE,
return_list = TRUE
)
axis_ls[[1]]
# Or, to select every other factor level:
axis_ls <-
pretty_axis(side = 1:2,
x = list(dx, dy),
pretty = list(list(), list(n = 5)),
units = list(2, NULL),
add = FALSE,
return_list = TRUE
)
axis_ls[[1]]
#### Examples with pi notation
## Define an example lunar phase time series
x <- seq.Date(as.Date("2016-01-01"), as.Date("2016-02-01"), by = 1)
y <- lunar::lunar.phase(x)
## Under the default options, pi notation is suppressed
x <- 1:10
y <- 1:10
axis_ls <- pretty_axis(side = 1:2,
x = list(x, y),
pretty = list(n = 5),
return_list = TRUE
)
lapply(axis_ls, function(x) x$axis[c("at", "labels")])
## To use pi notation for all axes with default args, specify list()
axis_ls <- pretty_axis(side = 1:2,
x = list(x, y),
pretty = list(n = 5),
pi_notation = list(),
return_list = TRUE
)
lapply(axis_ls, function(x) x$axis[c("at", "labels")])
## To use pi notation for specific axes, specify a nested list():
axis_ls <- pretty_axis(side = 1:2,
x = list(x, y),
pretty = list(n = 5),
pi_notation = list(NULL, list()),
return_list = TRUE
)
lapply(axis_ls, function(x) x$axis[c("at", "labels")])
## Pass arguments to pi_notation() to customise the result
axis_ls <- pretty_axis(side = 1:2,
x = list(x, y),
pretty = list(n = 5),
pi_notation = list(NULL, list(as_fraction = FALSE))
)
lapply(axis_ls, function(x) x$axis[c("at", "labels")])
#### The influence of NAs
# For all data types, NAs are removed with a message:
pretty_axis(x = list(factor(c(1, 2, NA)), 1:3))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.