Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export(tpar)
export(type_boxplot)
export(type_errorbar)
export(type_glm)
export(type_hist)
export(type_histogram)
export(type_jitter)
export(type_lm)
export(type_loess)
Expand Down
38 changes: 28 additions & 10 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,41 @@ where the formatting is also better._

Breaking changes:

* Type-specific arguments are no longer passed through the main function via
`...`. Instead, they are now passed through a dedicated `type_*()` functions in
the `type` argument.
- Type-specific arguments (i.e., affecting the default behaviour of a certain
plot type) should no longer be passed via `...` in the main plotting function.
Instead, these additional arguments must now be passed explicitly as part of the
corresponding `type_*()` function in the `type` argument. So, for example, you
should now use `plt(Nile, type = type_histogram(breaks = 30))` instead of
`plt(Nile, type = "histogram", breaks = 30)` if you wanted to adjust the number
of breaks. More details are provided below and also in the new dedicated
[Plot types vignette](https://grantmcdermott.com/tinyplot/vignettes/types.html).
The essential idea is that shortcut character types (here: `"histogram"`) all
still work, but are deliberately limited to default behaviour. In contrast, the
functional equivalents (here: `type_histogram()`) are where we can customize
behaviour by passing appropriate arguments. We're sorry to introduce a breaking
change, but this new approach should ensure that users have better control of
how their plots behave, and avoids guesswork on our side.

New features:

- Alongside the standard character shortcuts (`"p"`, `"l"`, etc.), the `type`
argument now accepts functional `type_*()` equivalents. These functional plot
types enable a variety of additional features. (#222 @vincentarelbundock)
- New model-based plot types:
- `type_glm()` (shortcut: `"glm"`)
- `type_lm()` (shortcut: `"lm"`)
- `type_loess()` (shortcut: `"loess"`)
- Explicit argument passing for modified behaviour type
(e.g., `type_lm(se = FALSE)`).
- Users can define their own custom types by creating `type_<typename>()`
functions.
- More details are provided in the dedicated
[Plot types vignette](https://grantmcdermott.com/tinyplot/vignettes/types.html)
on the website.
- The new `flip` argument allows for easily flipping (swapping) the orientation
of the x and y axes. This should work regardless of plot type, e.g.
`plt(~Sepal.Length | Species, data = iris, type = "density", flip = TRUE)`.
(#216 @grantmcdermott)
- New plot types added in #222:
- `type_glm()` (shortcut: `"glm"`)
- `type_lm()` (shortcut: `"lm"`)
- `type_loess()` (shortcut: `"loess"`)
- Custom types can now be defined by users by creating `type_typename()`
functions. (#222 @vincentarelbundock)
- Types vignette on the website. (#222 @vincentarelbundock)

Bug fixes:

Expand Down
7 changes: 3 additions & 4 deletions R/tinyplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,7 @@
#' specified.
#' @param xaxt,yaxt character specifying the type of x-axis and y-axis, respectively.
#' See `axes` for the possible values.
#' @param ... other graphical parameters (see \code{\link[graphics]{par}}), or
#' arguments passed to the relevant plot type (e.g., `breaks` for
#' `type = "histogram"`, or `varwidth` for `type = "boxplot"`).
#' @param ... other graphical parameters (see \code{\link[graphics]{par}}).
#'
#' @returns No return value, called for side effect of producing a plot.
#'
Expand Down Expand Up @@ -1216,7 +1214,8 @@ tinyplot.formula = function(
}

## nice axis and legend labels
if (!is.null(type) && isTRUE(type %in% c("hist", "histogram"))) {
hist_type = (is.atomic(type) && type %in% c("hist", "histogram")) || (!is.atomic(type) && identical(type$name, "histogram"))
if (!is.null(type) && hist_type) {
if (is.null(ylab)) ylab = "Frequency"
if (is.null(xlab)) xlab = xnam
} else if (is.null(y)) {
Expand Down
32 changes: 27 additions & 5 deletions R/type_histogram.R
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
type_histogram = function() {
#' Histogram type
#'
#' @md
#' @description Type function for histogram plots. `type_hist` is an alias for
#' `type_histogram`.
#' @param breaks Passed to \code{\link[graphics]{hist}}. One of:
#' - a vector giving the breakpoints between histogram cells,
#' - a function to compute the vector of breakpoints,
#' - a single number giving the number of cells for the histogram,
#' - a character string naming an algorithm to compute the number of cells (see ‘Details’ of \code{\link[graphics]{hist}}),
#' - a function to compute the number of cells.
#' In the last three cases the number is a suggestion only; as the breakpoints
#' will be set to pretty values, the number is limited to 1e6 (with a warning if
#' it was larger). If breaks is a function, the x vector is supplied to it as
#' the only argument (and the number of breaks is only limited by the amount of
#' available memory).
#' @export
type_histogram = function(breaks = "Sturges") {
out = list(
data = data_histogram(),
data = data_histogram(breaks = breaks),
draw = draw_rect(),
name = "histogram"
)
class(out) = "tinyplot_type"
return(out)
}
#' @export
#' @name type_hist
#' @rdname type_histogram
type_hist = type_histogram


data_histogram = function() {
fun = function(by, facet, ylab, col, bg, ribbon.alpha, datapoints, breaks = NULL, ...) {
hbreaks = ifelse(!is.null(breaks), breaks, "Sturges")
data_histogram = function(breaks = "Sturges") {
hbreaks = breaks
fun = function(by, facet, ylab, col, bg, ribbon.alpha, datapoints, .breaks = hbreaks, ...) {
hbreaks = ifelse(!is.null(.breaks), .breaks, "Sturges")

if (is.null(ylab)) ylab = "Frequency"
if (is.null(by) && is.null(palette)) {
Expand Down
15 changes: 9 additions & 6 deletions inst/tinytest/test-histogram.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ f = function() {
with(
iris,
plt(
Petal.Length, by = Species, type = "hist",
fill = 0.4, breaks = 30, palette = "classic"
Petal.Length, by = Species,
type = type_histogram(breaks = 30),
fill = 0.4, palette = "classic"
)
)
}
Expand All @@ -42,8 +43,9 @@ f = function() {
with(
transform(iris, long_sepal = paste("Long sepal:", Sepal.Length > mean(Sepal.Length))),
plt(
Petal.Length, by = Species, facet = long_sepal, type = "hist",
fill = 0.4, breaks = 30, palette = "classic", frame = FALSE, grid = TRUE
Petal.Length, by = Species, facet = long_sepal,
type = type_histogram(breaks = 30),
fill = 0.4, palette = "classic", frame = FALSE, grid = TRUE
)
)
}
Expand All @@ -54,8 +56,9 @@ f = function() {
~Petal.Length | Species,
data = transform(iris, long_sepal = paste("Long sepal:", Sepal.Length > mean(Sepal.Length))),
facet = ~long_sepal,
type = "hist", fill = 0.4,
breaks = 30, palette = "classic", frame = FALSE, grid = TRUE,
type = type_histogram(breaks = 30),
fill = 0.4,
palette = "classic", frame = FALSE, grid = TRUE,
)
}
expect_snapshot_plot(f, label = "hist_grouped_faceted")
Expand Down
4 changes: 1 addition & 3 deletions man/tinyplot.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions man/type_histogram.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.