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
5 changes: 3 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# plot2 0.0.2.9006 (development version)
# plot2 0.0.2.9007 (development version)

Breaking changes:

Expand All @@ -16,7 +16,8 @@ New features:
- Both the `pch` and `lty` arguments now accept a "by" convenience keyword for
automatically adjusting plot characters and line types by groups (#28,
@grantmcdermott).
- Point-range plots with `type="pointrange"` (#35 @vincentarelbundock)
- Add support for `type="pointrange"` and `type="errobar"` plots (#35
@vincentarelbundock and #40 @grantmcdermott)

Bug fixes:

Expand Down
61 changes: 53 additions & 8 deletions R/plot2.R
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@
#' not be specified in the same call.
#' @param data a data.frame (or list) from which the variables in formula
#' should be taken. A matrix is converted to a data frame.
#' @param type 1-character string giving the type of plot desired. The
#' following values are possible, for details, see plot: "p" for points, "l"
#' @param type character string giving the type of plot desired. Options are:
#' - The same set of 1-character values supported by plot: "p" for points, "l"
#' for lines, "b" for both points and lines, "c" for empty points joined by
#' lines, "o" for overplotted points and lines, "s" and "S" for stair steps
#' and "h" for histogram-like vertical lines. "n" does not produce
#' any points or lines. "pointrange" draws point-range plots.
#' any points or lines.
#' - Additional plot2 types: "pointrange" draws point range plots and
#' "errorbar" draws error bar plots.
#' @param xlim the x limits (x1, x2) of the plot. Note that x1 > x2 is allowed
#' and leads to a ‘reversed axis’. The default value, NULL, indicates that
#' the range of the `finite` values to be plotted should be used.
Expand Down Expand Up @@ -256,12 +258,27 @@ plot2.default = function(
if (is.null(ylab)) ylab = deparse(substitute(y))
if (is.null(legend.args$title)) ltitle = deparse(substitute(by))

xlabs = NULL
if (type %in% c("pointrange", "errorbar")) {
if (is.character(x)) x = as.factor(x)
if (is.factor(x)) {
## Need to maintain order that was observed in the original data
## (i.e., no new sorting by factor)
xlvls = unique(x)
x = factor(x, levels = xlvls)
xlabs = seq_along(xlvls)
names(xlabs) = xlvls
x = as.integer(x)
}
}

if (is.null(xlim)) xlim = range(x, na.rm = TRUE)
if (is.null(ylim)) ylim = range(y, na.rm = TRUE)

if (!is.null(ymin)) ylim[1] = min(c(ylim, ymin))
if (!is.null(ymax)) ylim[2] = max(c(ylim, ymax))


if (!is.null(by)) {
l = list(x=x, y=y)
l[["ymin"]] = ymin
Expand Down Expand Up @@ -401,14 +418,18 @@ plot2.default = function(

# axes, plot.frame and grid
if (axes) {
axis(1)
if (type %in% c("pointrange", "errorbar") && !is.null(xlabs)) {
axis(1, at = xlabs, labels = names(xlabs))
} else {
axis(1)
}
axis(2)
}
if (frame.plot) box()
if (!is.null(grid)) grid

# draw the points/lines
if (type %in% "pointrange") { # segments before point
## segments/arrows before points
if (type == "pointrange") {
invisible(
lapply(
seq_along(split_data),
Expand All @@ -417,13 +438,37 @@ plot2.default = function(
x0 = seq_along(split_data[[i]]$x),
y0 = split_data[[i]]$ymin,
x1 = seq_along(split_data[[i]]$x),
y1 = split_data[[i]]$ymax
y1 = split_data[[i]]$ymax,
col = col[i],
lty = lty[i]
)
}
)
)
}
if (type == "errorbar") {
invisible(
lapply(
seq_along(split_data),
function(i) {
graphics::arrows(
x0 = seq_along(split_data[[i]]$x),
y0 = split_data[[i]]$ymin,
x1 = seq_along(split_data[[i]]$x),
y1 = split_data[[i]]$ymax,
col = col[i],
lty = lty[i],
length = 0.05,
angle = 90,
code = 3
)
}
)
)
}
if (type %in% c("p", "pointrange")) {

## now draw the points/lines
if (type %in% c("p", "pointrange", "errorbar")) {
invisible(
lapply(
seq_along(split_data),
Expand Down
26 changes: 15 additions & 11 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -227,21 +227,25 @@ with(airquality, plot2(
))
```

### Point-range
### Point range and error bar plots

`plot2` adds a new `type="pointrange"` option to draw point-ranges plots:
`plot2` adds supports for point range and error bar plots via the `"pointrange"`
and `"errorbar"` type arguments. An obvious use-case is for regression
coefficient plots.

```{r pointrange, warning = FALSE}
mod = lm(mpg ~ hp + factor(cyl), mtcars)
mod = lm(Temp ~ 0 + factor(Month), airquality)
coefs = data.frame(names(coef(mod)), coef(mod), confint(mod))
coefs = setNames(coefs, c("x", "y", "ymin", "ymax"))
with(coefs,
plot2(pch = 17,
x = 1:4,
y = y,
ymin = ymin,
ymax = ymax,
type = "pointrange"
coefs = setNames(coefs, c("term", "estimate", "ci_low", "ci_high"))

with(
coefs,
plot2(
x = term, y = estimate,
ymin = ci_low, ymax = ci_high,
type = "pointrange",
pch = 19,
main = "Effect on Temperature"
)
)
```
Expand Down
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,22 +234,25 @@ with(airquality, plot2(

<img src="man/figures/README-desnity_topright-1.png" width="100%" />

### Point-range
### Point range and error bar plots

`plot2` adds a new `type="pointrange"` option to draw point-ranges
plots:
`plot2` adds supports for point range and error bar plots via the
`"pointrange"` and `"errorbar"` type arguments. An obvious use-case is
for regression coefficient plots.

``` r
mod = lm(mpg ~ hp + factor(cyl), mtcars)
mod = lm(Temp ~ 0 + factor(Month), airquality)
coefs = data.frame(names(coef(mod)), coef(mod), confint(mod))
coefs = setNames(coefs, c("x", "y", "ymin", "ymax"))
with(coefs,
plot2(pch = 17,
x = 1:4,
y = y,
ymin = ymin,
ymax = ymax,
type = "pointrange"
coefs = setNames(coefs, c("term", "estimate", "ci_low", "ci_high"))

with(
coefs,
plot2(
x = term, y = estimate,
ymin = ci_low, ymax = ci_high,
type = "pointrange",
pch = 19,
main = "Effect on Temperature"
)
)
```
Expand Down
73 changes: 73 additions & 0 deletions inst/tinytest/_tinysnapshot/pointrange_errorbar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 70 additions & 0 deletions inst/tinytest/_tinysnapshot/readme_pointrange.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions inst/tinytest/test-README.R
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,23 @@ f = function() {
}
expect_snapshot_plot(f, label = "readme_palette_tableau")

f = function() {
mod = lm(Temp ~ 0 + factor(Month), airquality)
coefs = data.frame(names(coef(mod)), coef(mod), confint(mod))
coefs = setNames(coefs, c("term", "estimate", "ci_low", "ci_high"))
with(
coefs,
plot2(
x = term, y = estimate,
ymin = ci_low, ymax = ci_high,
type = "pointrange",
pch = 19,
main = "Effect on Temperature"
)
)
}
expect_snapshot_plot(f, label = "readme_pointrange")

f = function() {
par(pch = 16, family = "HersheySans")

Expand Down
Loading