If you are viewing this file on CRAN, please check the latest NEWS on our website where the formatting is also better.
type_lines() and its shortcut equivalents like
"l" and "b" now order categorical
x data by (coerced) factor levels, rather than simple order
of appearance. This resolves a longstanding tension between line types
and other types like type_points(), which have always
ordered the x axis by implied factor levels. It also
improves layering consistency via plt_add() and co. so that
plots are identical, regardless of whether lines are layered on top of
points, or vice versa. Note that you can still select into the old
behaviour by passing the (new) xord = "asis" argument as an
explicit override; see “Other new features” below. (#683 1)type_hexbin() / "hexbin" for hexagonal bin
plots, a 2D analogue of a histogram. (#667 1)type_tile() / "tile" for tile plots,
i.e. a grid of rectangles whose fill encodes a third variable. (#677
1)type_heatmap() / "heatmap" builds on
type_tile(), adding a scale argument that
scales the fill values within each category of one axis. This
is analogous to base R’s heatmap() function, and like the
latter it z-scores along the chosen margin by default. It also reverses
the y-axis by default, so that the first row sits at the top (again
matching heatmap()); pass an explicit ylim to
override. (#677 1)type_sina() / "sina" for sina plots, a variant
of the violin plot where the raw observations are displayed as points,
with each group’s width bounded by its density. This makes them arguably
a more principled version of the beeswarm plot. (#734 1)type_area() gains a
new stack argument for drawing stacked area plots,
where each layer represents a discrete by category group.
This functionality is further enhanced by two (also new) sister
arguments. First, byord enables on-the-fly (re-)ordering of
the stacked by layers, via convenience keywords or custom
functions (e.g., byord = "end" ranks groups according to
their largest final value). Second, a fun argument permits
stacking of multi-observation data by collapsing repeated y
values. (#688 1)The top-level facet.args list argument gains several new
(sub-)arguments that enable finer control and customization of faceted
plots:
axes: gives explicit control over which facets draw
their own axes: "all", "outer" (drop redundant
interior axes), or "none". Previously this was only
achievable as a side effect of frame.plot = FALSE, so
axes = "outer" now allows redundant axes to be dropped
while keeping the facet frames. Left unspecified, the behaviour
is still inferred from whether the plot is framed. (#661, #673 1)
"classic",
"socviz", "tufte", and "float")
now default to facet.axes = "outer", so that they drop the
redundant interior axes of faceted plots.drop: allows for the removal of empty facets. The
behaviour varies slightly depending on whether a one-sided (wrapped) or
two-sided (gridded) facet formula is specified. The former simply
removes the missing factor level, while the latter retains its spot (to
preserve the rectangular grid) but is not drawn. (#708, #710 1)drop.levels: allows each free facet
(free = TRUE) to keep only the categories of a categorical
axis that it actually uses. The panel’s axis is recomputed as if its own
data had been passed through factor(), so that the
surviving categories are re-spaced evenly rather than leaving a gap
where an unused one sat. Note the distinction from drop
above: the latter removes empty facets, whereas
drop.levels removes unused categories within a
facet. Default is FALSE, i.e. every facet keeps the full
set of categories. (#718 1)labeller: for formatting facet titles via
tinylabel(). Accepts the usual mix of convenience keywords
(symbols) known to tinylabel(), or formatting functions. A
(named) vector or list can be used to separately format multi-variable
facets, e.g. labeller = c(country = toupper, size = ",").
(#684 1)prefix: for adding an informative prefix to facet
titles. In its simplest form, prefix = TRUE prepends the
facet variable name, e.g. "vs = 0" and
"vs = 1" (rather than just "0" and
"1"). Like labeller above, multi-variable
facets can be prefixed separately via a (named) vector or list,
e.g. prefix = c(am = "Automatic", vs = "V-shaped"). (#684
1)sep: controls how the individual variables of a
multi-variable facet title are separated, e.g. use
sep = "\n" to stack on separate lines rather than
concatenating via the default ":". (#684 1)Note that each of these facet.args arguments is paired
with an equivalent tpar(facet.<arg>) parameter. For
example, call tpar(facet.axes = "outer") to set this
behaviour globally. This also means that they can be set as part of a
(custom) theme,
e.g. tinytheme("clean", facet.axes = "outer").
This release brings several enhancements for working with
categorical variables, i.e. where x,
y, or by are characters or factors with
discrete levels. This includes improvements to existing arguments, as
well as the provision of some new arguments that enable finer control
over level ordering and convenient label formatting.
xlevels, ylevels: these (type-level)
arguments permit on-the-fly reordering of a categorical variable via
literal specification, either a character vector of level names
(e.g., c("C", "B", "A")), or a numeric vector of level
indices (e.g., 3:1). While this argument is not new—having
been supported by type_barplot and several other types for
a while—we now extend xlevels support to
type_points(), type_lines(),
type_errorbar(), and type_pointrange(). (#683,
#694 1)xord, yord: these are new (type-level)
arguments that provide an alternate ordering interface to
x/ylevels. Specifically, while x/ylevels
require a literal ordering, x/yord computes the
order on the fly, according to (type-appropriate) convenience keywords
or a custom ranking function. For example,
"desc(ending)"/"asc(ending)" orders by value,
while "asis" ignores factor levels and just takes the order
of appearance in the data as given. Among other things, this makes it
possible to sort barplots by height (e.g.,
type_barplot(xord = "desc")), or ridges by their spread
(e.g., type_ridge(yord = "minvar")) without relevelling the
underlying factor by hand. (#683, #694 1)x/ylevels and x/yord are
provided, the former takes precedence as the more explicit.)tinylabel() gains a dictionary form, i.e., a
named character vector or list that maps existing labels to new
ones a la c(old1 = "new1", old2 = "new2"). Partial
mapping is fine since the lookup is by value rather than by position, so
that some levels can be left unnamed. Importantly, this behaviour
extends to the rest of tinyplot’s (re)labelling
machinery—including x/yaxl, type_text(), and
any function with a labeller argument—since everything is
routed through tinylabel(). (#690 1)x/yaxlabels arguments of
type_spineplot() and type_barplot() are
deprecated in favour of the top-level x/yaxl arguments. The
type-level arguments predated their top-level cousins, which now offer
the same functionality via a consistent interface across all
types. The old arguments still work (with a warning) for now. But we
will be formally removing them in a future release and, going forwards,
encourage users to move over to xaxl and yaxl
as the idiomatic tinyplot way to relabel and format
axis ticks. (#692 1)Beyond convenience, these improvements to categorical variable handling also provide the scaffolding to eliminate some niggling inconsistencies; for example, related to plot layering. See “Bug fixes” below.
"p", "l",
"errorbar", and friends) gain smart padding behaviour for
categorical axes. Most notably, we now use more generous axis padding
when there are few unique categories (levels), so that the end tick
marks aren’t drawn flush against the plot frame. Users can also override
with the new x/ypad arguments (see below) to match their
own aesthetic preferences. (#732 1)tinyplot.* methodstinyplot.array(): for (unclassed) array
objects with up to four dimensions. This extends the
tinyplot.matrix() conventions by mapping the third
dimension to facets, and a fourth to a facet grid. The names of the
dimnames (if any) are used for the axis, legend, and facet titles.
Arrays with a length-2 dimension (e.g., gait) are plotted
as x/y pairs, i.e. one slice against the other. See the
tinyplot.array-specific xy argument. Passing
facet = FALSE draws everything in a single panel instead.
(#746 1)tinyplot()/plt() arguments:
xpad and ypad enable control over how much
padding (as a fraction of the data range) is added to each end of the
axes. Following base R conventions, the default for most plots is
0.04, i.e. 4% padding on each side. Also settable globally
via tpar(xpad = <xpad>, ypad = <ypad>). (#729
1)xaxr and yaxr enable rotating of the x-
and y-axis tick labels by arbitrary angles, closing a long-standing
feature request (#346). Note that setting one overrides las
for that axis. Best combined with a dynamic theme, since the plot
margins are resized to fit the rotated labels. Also settable globally
via tpar(xaxr = <xaxr>, yaxr = <yaxr>) and thus
as part of a tinytheme too. (#717 1)las does the same thing, but limited to the four right
angles of base R’s par(las=) convention, having previously
been settable only via tpar() or a theme. Note that this
top-level argument applies to a single plot only and takes precedence
over the active theme, so it can also be used to opt out of a
theme’s las,
e.g. tinyplot(..., theme = "clean", las = 0). (#353 1)record enables recording plots as
replayable objects, closing another long-standing feature request
(#121). Specifically, setting record = TRUE returns a
"recordedtinyplot" object (see
?recordedtinyplot), allowing for assignment and later
recall, e.g. myplot = tinyplot(...); myplot. Also settable
globally via tpar(record = TRUE), so that all
tinyplot() plots are automatically recorded—with potential
memory implications for detailed plots with many elements. Note
that a recorded plot will still render its display on the initialising
call if you are using an interactive graphics device. While we have done
our best to vet this new record functionality carefully,
users should still regard it as experimental. We may change its
behaviour (availability) in a future release if we observe undesirable
side-effects. Please help us by testing on your own machines and
reporting any issues. (#686 1)type_lines() and its shortcut equivalents like
"l" and "s" now support a continuous
by variable, drawing a colour gradient along the line
itself rather than reverting to a discrete legend. Useful for
trajectories, where a third variable (typically time) orders the path;
see the new ?type_lines examples. (#712 1)type_density() gains an echo.bw argument
for reporting the smoothing bandwidth and the number of observations
behind it, neither of which is visible from the curve itself.
Destinations are "sub", "cap", and
"cat" (console), in any combination; a destination the user
has already labelled is left alone. Shared bandwidths are reported once
and named as joint, individual bandwidths per group. (#287 @haomeng797-ship-it)type_area() gains a stack argument for
drawing stacked area plots. See “New plot types” above for more details.
(#688 1)type_summary() gains a dodge (and
fixed.dodge) argument, thus enabling dodging of grouped
plots. This is mostly useful for adding summaries on top of a base layer
that is itself dodged. Separately, type_summary()’s
internals have been refactored to use stats::aggregate
instead of stats::ave. (#701 1)type_barplot() gains a na.as.zero argument
for controlling whether a category that no observation reaches is
treated as a zero (and so marked with a flat bar along the baseline) or
left undrawn. The default NULL lets fun
decide; see the new “Implicit zeros and empty cells” section of
?type_barplot. (#718 1)type_barplot()’s aggregation argument is now spelled
fun, for consistency with the other types that take a
function and with tinyplot’s lowercase argument naming
generally. FUN is retained as a backwards-compatible alias,
so existing code keeps working; supply one or the other, and
fun takes precedence if both are given. (#695 1)type_histogram() now (correctly) supports mapping
by grouping along the x variable,
e.g. tinyplot(~mpg | mpg, data = mtcars, type = "hist").
Bar colours map to mean bin values. (#727 1)type_loess() is now much faster on large data. Thanks
to @eleuven for
bringing this slowness issue to our attention. (#509 1)"heatmap" provides a dedicated companion theme to the
new type_tile() and type_heatmap() types (see
above). The theme removes all axis padding, so that tiles meet the panel
edge, and also rotates the tick labels against their respective axes.
Colour fills default to the “tealgrn” sequential palette. (#677 1)tinytheme_get() function returns the name of the
currently active theme. (#629 1)type_hints mechanism. A type can
declare properties about itself—that it draws its own axes, needs a
secondary right-hand axis, uses proportional limits, fills its legend
key from col, and so on—and tinyplot
adjusts margins, axis limits and legend keys accordingly. Previously
this behaviour was hard-coded against the names of built-in types, so it
was unavailable to custom types. See Advanced
customization in the Types vignette for the list of
supported hints. (#543 1)cex.xaxs and cex.yaxs graphical
parameters allow the x- and y-axis tick labels to be sized
independently, e.g. tpar(cex.yaxs = 0.6) to shrink a long
list of category names on the y-axis without also shrinking the x-axis.
Both default to NULL, in which case the shared
cex.axis value is used, so existing plots are unaffected.
(#677 1)tinyplot(1:10, array(1:10, c(1, 10))) works just like
plot(). (#548, #746 @tony-aw @zeileis 1)facet = rows ~ cols) now work
with the default (non-formula) method,
e.g. tinyplot(x, y, facet = a ~ b, data = dat). Previously
this errored because data was not forwarded. (#746
facet.args = list(free = TRUE)) now
respect asp. (#744 1)"Hello\nWorld") are
now spaced correctly under dynamic themes. (#742 1)type_lm(), type_glm() and
type_loess() now space their prediction grid evenly in
log(x) when the x-axis is logarithmic. Previously a
log = "x" plot spanning several decades drew the left-hand
ones as a few straight segments. (#509 1)theme argument no longer clobbers a
persistent tinytheme() i.e., beyond the intended single
plot override. Similarly for a user’s own tpar() settings.
(#739 1)theme argument are no longer clipped to the wrong region.
Only triggered once an intervening annotation changed xpd
(e.g. box(), mtext(), or
type_text(xpd = NA)), since that is what makes base R
recompute the clipping rectangle. Thanks to @bastistician for the report. (#629
1)type_text() no longer converts a categorical axis to a
numeric one. (#730 1)type_hline(), type_vline(), and
type_abline() now respect flip = TRUE, so that
(e.g.) h refers to the flipped y variable and
is drawn vertically. Code that previously used type_vline()
as a workaround for a vertical line on a flipped plot should switch to
type_hline(), and vice versa. (#733 1)adjust argument of type_density(),
type_violin(), and type_ridge() was accepted
but never passed on to the underlying density() call, so it
silently did nothing. (#734 1)type_violin() receives two further bug fixes:
joint.bw = "full" computed the joint bandwidth from the
x categories rather than the y values being
smoothed. (#734 1)by variable’s
underlying integer codes. A numeric by therefore errored
outright, and a factor by carrying an unused level silently
dropped the affected group from the plot. Offsets are now keyed by
position among the observed groups. (#734 1)by now reverts to discrete
groups and a matching discrete legend, as it already did for
"boxplot", "polygon" and the other types that
cannot render a colour gradient. Previously every violin was drawn in
the same colour while the legend showed a colourbar. (#734 1)par("xlog")/par("ylog") state. We now avoid
this by grabbing the log state directly from the top-level
log argument instead. Thanks to @eddelbuettel for the report. (#725
1)type_barplot() receives several consistency
improvements and bug fixes:
barplot(). (#714 1)fun or the
new na.as.zero argument (above). At the same time, explicit
zeros remain unaffected. Again, see the new “Implicit zeros and empty
cells” section of ?type_barplot for details and examples.
(#711 1)type_ridge() no longer errors under themes that set a
relative (negative) numeric col.default,
e.g. theme = "classic". (#703 1)tinyplot_add() now align correctly on
a categorical axis:
x variable to a factor, as type_barplot() and
type_violin() do. The base layer’s categories are the
coerced labels, while the added layer still carried the raw
values, so it was drawn at those coordinates instead of at the category
positions—often well outside the plotting region. (#691 1)tinyplot(..., center = TRUE, yaxl = "percent") labelled its
axis 80.00000% rather than 80%. (#689 1)xaxl / yaxl arguments now
work for type_spineplot() and type_ridge().
Both types draw their own axes, and so never reached the standard path
where those arguments are applied, meaning they were silently ignored.
(#694 1)xlevels / ylevels no longer drop data
silently. Naming a strict subset of a variable’s levels sent every other
level to NA, quietly removing those observations from the
plot; this now warns. Supplying a value that matches no level at all is
now an error, rather than surfacing later as an unrelated complaint
about zero-length ranges. (#688, #694 1)type_area() now labels a categorical x
axis with its factor levels, rather than falling back to the underlying
integer positions. (#688 1)by and facet combinations containing only
one observation. Such groups are now dropped, together with a warning
reporting how many were removed. The affected
types—type_density(), type_violin(), and
type_ridge()—also gain a singletons argument
for controlling this behaviour: option "drop" removes them
quietly, while "none" retains them (and so requires a
numeric bw). (#687 1)flip = TRUE now flips the drawn geometry of the
single-letter line types, not just the axes: type = "h"
draws horizontal segments to the baseline, and the step types
"s" and "S" swap which coordinate moves first.
(#675 @haomeng797-ship-it)flip = TRUE and for a factor y
variable. Previously the y-axis fell back to numeric tick labels for
every line type except "p". (#679 1)facet.args = list(free = TRUE)):
drop.levels arg (above) for the opposite behaviour. (#718
1)'labels' is supplied and not 'at'. The free-facet code path
listed the eligible types by name, so any other type lost its tick
positions while keeping the corresponding labels, whether flipped
(e.g. type = "b" with flip = TRUE) or not
(e.g. type = "p" with a factor y variable).
(#679 1)par(usr) values. (#668 1)par(usr) values either. (#705 1)x/ylim overrides now work correctly with
flipped plots. (#670 1)x/ylim limits (e.g.,
ylim = 0 or ylim = c(0, NA)) are now resolved
per facet, rather than once against the range of the whole dataset.
(#706 1)cex, lwd
and lty as their fixed-scale counterparts. Previously the
free-facet code path built its axis calls by hand and so silently
ignored cex.axis, lwd.axis and
lty.axis (plus their per-side variants), which was most
visible under themes that set them, e.g. tinytheme("bw").
(#673 1)cex.axis as
cex, which base axis() ignores in favour of
cex.axis when sizing tick labels, so the setting had no
effect. This also means the per-side
cex.xaxs/cex.yaxs parameters (see above) take
effect. (#677 1)cex.axis, so a
plot setting cex.xaxs/cex.yaxs to different
values clipped the labels on the larger axis and reserved dead
whitespace on the smaller one, e.g.
tinytheme("heatmap", cex.xaxs = 2, cex.yaxs = 0.5). (#677
1)"spineplot" types
(e.g. facet = "by"), where the self-drawn axis labels were
overplotted several times and rendered too heavy. (#637 1)"spineplot" and "ridge"
types, which draw their own axes and so bypassed the shared outer-axis
logic, but some affected other types too. (#660, #661 1)
tinytheme("clean2")), where the category
labels previously spilled into the neighbouring facet.tinytheme("clean")). The tick-label
width was only reserved once, in the outer margin, which is correct only
when a single facet draws that axis.type = "boxplot", flip = TRUE) no
longer duplicate the category axis while omitting the interior x-axes,
which had left facets labelled against a neighbour’s scale.axes = "t" (and other tick-style axes) no longer drop
the interior facet labels.y ~ 1 formulas no longer silently drop
explicitly-typed layers,
e.g. tinyplot(body_mass ~ 1, data = penguins) followed by
tinyplot_add(type = type_vline(4500)). The x-axis swap
these formulas require was only applied when the type had to be
inferred, so an explicit type was mistaken for an empty plot and never
drawn. (#647 1
@zeileis)legend = "bottom!") no longer ride up over the x-axis
under dynamic themes. (#719 1)tinyplot v0.7.0 is a big release with many new features, including major updates to our theming logic and aesthetic stylings. Related updates are grouped below for easier navigation.
A major focus of v0.7.0 is bringing various aesthetic improvements to tinyplot. These aesthetic improvements should carry over to all of your (tiny)plots automatically and do not require any changes to user-facing inputs or the core API. From that perspective they are not a breaking change, even though some of your plots may look slightly different from before. Still, we hope that you agree the following changes result in better looking visualizations:
"right!" and
"left!". This is a minor visual change from the previous
default of centered legends, which we inherited from base R. However,
users can still override this behaviour with the new ljust
parameter, which accepts values of "l(eft)" (new default)
or "c(enter)" (old default). (#500 1)
tpar(ljust = "c"), or revert for a single plot by passing
the parameter as part of the legend list arguments,
i.e. plt(..., legend = list(ljust = "c")).legend = "direct" keyword. This places the legend labels at
the last observation of each data group and is thus best suited to line
or ribbon plots, where the data is sorted along the x-axis. (#587 1)
repel (for
automatic vertical separation) or
nudge_x/nudge_y (for manual per-group
offsets). For example,
plt(..., legend = list("direct", repel = TRUE)).We have significantly refactored our dynamic themes logic.
Recall, these are themes like "dynamic",
"clean", "bw", etc. that automatically adjust
margin spacing and related plot elements to reduce whitespace and
improve the overall plot aesthetic. The ?tinytheme help
file and online Themes
vignette cover the new features in detail. But see below for the
highlights. (#549, #591, #595, #606, #614 1, @vincentarelbundock, @zeileis)
New theme features:
tinytheme() now accepts additional
gap.axis and gap.lab “primitives”, providing
finer control for spacing between ticks-to-labels and labels-to-titles,
respectively, in dynamic themes. (#590 1)tinytheme() also accepts
gap.main and gap.sub primitives for
controlling the spacing between titles and the plot region. (#595
1)"tufte" and "void" are now dynamic
(responsive margins).ggplot2-inspired themes ("bw",
"classic", etc.) now use smaller axis text and tighter
spacing to better match their upstream ggplot2
counterparts."ipsum" has been similarly overhauled to match the
upstream theme (bold title, no ticks, fine grid, custom palette). Our
original tinyplot variant is preserved as
"ipsum2" for those who still want to use it."dark" now uses a better default
ribbon.alpha for better contrast against the black
background."dynamic" (new foundation for all other dynamic
themes)"broadsheet" (data journalism style à la
The Economist or NY Times)"float" (floating axes; a variant of
"tufte")"linedraw" (based on the ggplot2
theme)"nber" (NBER working paper style)"socviz" (based on Kieran Healy’s book)"web" (web publication, e.g. FiveThirtyEight)tinytheme_register() function for registering
custom user themes. Registered themes inherit from any built-in (or
previously registered) theme, apply user-specified overrides, and can
then be used by name with tinytheme(<theme>) or
tinyplot(..., theme = <theme>). Companion functions
tinytheme_list() and tinytheme_unregister()
further support this functionality. (#608 1)by grouping) versus
multi-group displays. The upshot is that, for many themes, single-group
displays will simply default to “black”, whereas multi-group displays
will drop “black” and only present colour palettes. This behaviour is
operationalized through the new col.default parameter,
settable via tpar() or within a theme. (#614 1 @zeileis)
"clean(2)", "dark", "nber",
"web") consistently use that colour for single-group
displays too."bw",
"classic", "linedraw", and
"minimal") continue to use black for single-group display.
But they now drop the leading black from their grouped
palettes. (Note that these themes also use the default
"ggplot2" palette now, so grouped plots start at the
familiar salmon hue.)"ipsum2" and "broadsheet"
themes use the Okabe-Ito palette less its leading black, so grouped
plots start at orange. The "float" and "void"
themes also default to black for single-group displays."boxplot",
"violin", "barplot", and
"histogram" displays is now unified across these four
types, so that a single-group plot looks the same regardless of which
one you reach for. (#614 1 @zeileis)
"clean" or the teal of "dark"), the
fill is a lighter-but-opaque tint of it; following the same sequential
HCL ramp that "ridge" type plots have been using for a
while."bw"/"classic"/"ipsum" themes),
all four types share a neutral "lightgray" fill, matching
base R’s hist() and boxplot() defaults. Note
that this does imply a change for "barplot" types, which
previously used a slightly darker "grey" (to match base R’s
barplot()), but we decided internal consistency was the
more important feature to prioritize."boxplot",
"violin", and "barplot" displays now also use
the lighter-but-opaque fill, so that grouped plots match their
single-group counterparts (previously grouped barplots used dark
saturated fills and grouped boxplots/violins used semi-transparent
fills). Each type gains a lighten argument (default
TRUE); set type_barplot(lighten = FALSE)
(etc.) to recover the fully-saturated palette colours.
"histogram" is deliberately excluded, since
semi-transparency remains preferable for overlapping grouped
distributions. "spineplot" also gains a
lighten argument (only relevant for the
y == by case), but defaults to FALSE
(saturated fills): its tiles abut one another with no gap, so the darker
fills read better against their matching border colours. (#646 1 @zeileis)
fill or
alpha is now layered on top of the (lightened)
fill rather than the saturated base colour. This fixes a
counterintuitive case where adding an alpha fill
(e.g. fill = 0.7) could darken the interior of an
area-based plot.Theme fixes:
main, sub, and x/y
axis titles. For example, a plot without a main (or
sub) title will expand to the top of the device region to
reduce excess whitespace. (#303)main and sub titles now
correctly anchor to the y-axis line, even when long horizontal tick
labels widen the left margin. (#479)cex.xlab and cex.ylab now correctly
control axis title size. The more general cex.lab is still
respected as a fallback. (#574)mgp now scale correctly with
cex.axis and cex.lab, maintaining constant
visual gaps between axis elements regardless of text size. From the user
perspective, this is operationalized through the new
gap.axis and gap.lab theme primitives, which
let you control the spacing between margin elements directly
(tick-to-label gap and label-to-title gap, respectively), replacing the
guesswork of manually combining mar, mgp, and
tcl values. (#590)gap.main and gap.sub theme primitives
control the spacing between titles and the plot box.
gap.main sets the gap from the main title to whatever is
below it (plot box or subtitle top); gap.sub sets the gap
from the subtitle to the plot box. Both default to 0.7.
(#597)legend = "top!".
The title, subtitle, and legend stack correctly above the plot region
with proper spacing. (#605)type_chull() (equivalently,
type = "chull") for drawing convex hulls around grouped
points. Uses grDevices::chull() under the hood and
delegates drawing to draw_polygon(). Works well as a layer
on top of points, e.g. plt_add(type = "chull", fill = 0.2).
(#600 1)type_ellipse() (equivalently,
type = "ellipse") for drawing confidence ellipses around
grouped points. Like type_chull, works well as a filled
layer, e.g. plt_add(type = "ellipse", fill = 0.2). (#610
1)tinyplot.*
methodstinyplot.data.frame(): Supports direct plotting of
data frames, alongside the new top-level function
tinypairs(). Can be called with or without a formula. One
benefit of the former is that it facilitates piping, e.g.
iris |> plt(Sepal.Length ~ Petal.Width | Species)If no formula is provided, then the behaviour depends on the number
of variables (columns) in the data frame. For example, a dataset with 3
or more variables will yield a pairs()-style grid of all
variable combinations. Thanks to @mthulin for the suggestion and original
implementation idea. (#613, #640 @zeileis 1)
tinyplot.matrix(): for matrix objects,
e.g.
plt(VADeaths, type = "b")The output largely mimics the base
matplot/matlines equivalents, but with
additional tinyplot functionality related to automatic
legends, options for faceting, etc. (#649 1)
tinyplot.ts(): for ts time series,
e.g.
plt(EuStockMarkets)Produces a line plot by default, although users can override by
passing an explicit type argument. Similarly, multivariate
series are faceted by default, but users can also override to obtain,
say, a single frame with direct labels. (#558 @zeileis 1)
New and updated top-level
tinyplot()/plt() arguments:
cap = <string> for adding a caption to your
plots. Captions are drawn at the bottom of the plot and are best paired
with dynamic themes (since separation from sub is
guaranteed). Appearance is customizable via tpar()
parameters: adj.cap, cex.cap,
col.cap, font.cap, and line.cap.
(#592 1)
weights = <varname> for adding weights to
statistical transformations. Supported types are models
(type_lm(), type_glm(),
type_loess()) and distributions
(type_density(), type_histogram(),
type_spineplot()). A warning is emitted if
weights is passed to an unsupported type and the argument
is also ignored. The top-level weights argument supports
non-standard evaluation (NSE) in the formula method, so that bare column
names can be passed for convenience. Users can also pass a weights
argument directly at the type-specific function level, but this must be
a vector of correct length (no NSE). For example:
plt(y ~ x, data = dat, type = "lm", weights = w) # top-level, NSE
plt(y ~ x, data = dat, type = type_lm(weights = dat$w)) # type-level, vectorIn addition to NSE convenience, the top-level variant is preferred since it is correctly matched to the model frame construction with the formula method (e.g., so missing values are handled automatically). Thanks to @eleuven for the original suggestion, as well as various discussion participants for helping to frame the scope. (#639 1)
labels = <varname> for passing labels to
type = "text". Like the new weights argument
(above), the main benefit is the convenience of NSE, as well as the
automatic handling of missing values and subsets as part of the model
frame construction. For example, compare:
plt(y ~ x, data = dat, type = "text", labels = labs, subset = x < 10)
plt(y ~ x, data = subset(dat, x < 10), type = type_text(labels = subset(dat, x < 10)$labs))The labels arg is silently ignored for non-text types.
(#639 1)
The grid argument (and tpar("grid"))
now accepts character strings to control axis-specific grids at
different resolutions. Uppercase letters ("X",
"Y", "XY") draw grid lines at the standard
tick positions, while lowercase letters ("x",
"y", "xy") draw a finer grid with additional
lines at the midpoints between ticks. Thanks to @zeileis for the suggestion. (#578
1)
Facet formulas now support 1 as a convenience syntax
for single row or column arrangements. (#562 @zeileis)
plt(..., facet = z ~ 1) <->
plt(..., facet = ~z, facet.args = list(ncol = 1))plt(..., facet = 1 ~ z) <->
plt(..., facet = ~z, facet.args = list(nrow = 1)).x/ylim gain several “smart” override forms. (#644
1)
ylim = 0) ensures that value is
covered by the axis range, e.g. for forcing zero onto a coefficient
plot.NA
(e.g. ylim = c(0, NA)) pins the non-NA limit
and lets the data determine the other."rev" (or "reverse") reverses
the auto-computed axis range, without needing to know the data extent in
advance.Type-specific updates:
type_barplot() gains an offset argument
for shifting bar baselines away from zero. (#611, #615 1 @zeileis)
by group, pulling
them out of the stack and drawing them as standalone bars. This is
useful for Likert plots, where you want to show a neutral category
(e.g., “Unsure”) apart from the diverging stack. Thanks to @strengejacke for the
suggestion.type_text() gains two new arguments:
labeller argument that is passed to
tinylabel() for formatting the text labels. (#620 1)repel argument that automatically nudges overlapping
text labels apart. One limitation is that the repulsion logic operates
within groups. So there may still be some overlapping text for grouped
data. (#621 1)weights
argument; although this is best provided from the top-level
tinyplot()/plt() call. See above.legend = list(title = FALSE) now suppresses the
legend title, matching the existing title = NULL behaviour.
(#653 1)
grid = grid() not drawing grid lines on all
facets. That said, logical or character inputs (e.g.,
grid = TRUE, grid = "xy") remain the more
idiomatic way to generate a background grid in tinyplot.
(#193 1)facet.cex; inter-panel gaps for multiline facet titles
remain fixed regardless of strip height; and strip text is now
vertically centered within the background rect. (#586 1)palette.qualitative in themes
could not be a function. Thanks to @katrinabrock for the report. (#594
@zeileis)type_polygon,
type_chull, and type_ellipse when
density is set. (#610 1)tinylabel()
currency and comma formatters (e.g., "$", "€",
"£", ","). These now use a consistent number
of decimal places across the whole vector, matching the existing
behaviour of the percent formatter. The currency formatters additionally
show at least two decimal places whenever a fractional component is
present (e.g. "$0.50" rather than "$0.5"),
while still keeping clean integers integer-valued
(e.g. "$1,000"), and place the negative sign in front of
the currency symbol (e.g. "-$1.50" rather than
"$-1.50"). (#618, #623 1)xlab = NA / ylab = NA gotchas for
"barplot", "spineplot", and
"ridge" types. (#635, #650 1)tinyplot_add() (plt_add()) now captures
its arguments unevaluated, so arguments that rely on non-standard
evaluation against data (e.g.,
plt_add(..., subset = <>)) resolve correctly instead
of erroring with “object not found”. (#638 1)plt(..., ann = FALSE) correctly turns off title
annotations now, fixing a regression that we missed from at least
v0.6.0. Thanks to @bastistician for the report. (#641
@zeileis)bquote() (and other unevaluated language)
annotations such as main, sub,
cap, xlab, and ylab being
evaluated instead of coerced to plotmath expressions,
e.g. plt(0, 0, main = bquote(foo == .(pi))). Thanks (again)
to @bastistician
for the report. (#642 1)type = "l", and relatives like
"b"/"o") with a factor or character
x variable now draw the category labels on the x-axis,
matching the behaviour of point plots. Previously these tick labels were
only shown when dodging was active. (#648 1)legend = FALSE. (#656 1)"pointrange" and
"errorbar" types now include a line, to better resemble the
actual plot elements (#533 1)y ~ 1,
~ x, and ~ 0. These are translated to
x = NULL or y = NULL in the default method
call, with automatic type inference: y ~ 1 (numeric)
produces a histogram, y ~ 1 (factor) produces a barplot,
~ x (factor) produces a barplot, and ~ x
(numeric) produces a scatterplot against the index. The ~ 0
form is useful for types that don’t require x/y, such as
segments and rect. Thanks to @katrinabrock for the
suggestion. (#534 @zeileis 1)facet.args = list(free = TRUE)
lead to an error when used without facets. Thanks to @katrinabrock for the
report. (#554 @zeileis)type_ridge() fill errors for themes that set a
qualitative palette, e.g. "clean2". (#564 1)theme = "default" with a legend and
tinyplot_add(). Thanks to @katrinabrock for the report in #557.
(#565 1)tinyplot_add(type = "jitter") no longer errors when
layered on top of boxplot, violin, or similar categorical plot types.
(#560 1)tinyplot_add() now align
correctly with grouped (offset) boxplot, violin, and ridge base layers.
(#561 1)Types vignette. (#531 1)type_<type> constructors. (#531 1).CLAUDE.md context file for AI-assisted
development. (#563 1)revdep* branch. (#567 1)tinyplot
calls are now stored in a dedicated (temporary) internal environment
called settings, which can be accessed and modified by
type-specific functions. This change will enable various internal
enhancements, from improving the modularity and maintainability of the
tinyplot codebase, to reducing memory overhead and
performance (since we require fewer object copies). Looking ahead, we
also expect that it will make it easier to support new features and
integration with downstream packages. Most tinyplot users
should be unaffected by these internal changes. However, users who have
defined their own custom types will need to make some adjustments to
match the new settings logic; details are provided in the
updated Types vignette. (#473 @vincentarelbundock and 1)fixed.pos argument for dodged plots has
been renamed to fixed.dodge to avoid ambiguity, especially
when passed down from a top-level tinyplot(...) call. (#528
1)type_text() gains a family argument for
controlling the font family, separate to the main plot text elements.
(#494 1)dodge argument capabilities and consistency
for dealing with overlapping groups:
dodge argument now also supported by
type_lines(), type_points(), and
type_ribbon(). (#522, #528 1)dodge values must be in the
range [0,1). (#526 1)dodge = TRUE argument, which gives automatic width spacing
based on the number of groups. (#525 1)fixed.pos ->
fixed.dodge, per the breaking change above. (#528 1)pretty breaks algorithm that we use to create discrete
legend categories. The interior plot elements, e.g. bubble points, are
unaffected. (#498 1)type_text() now defaults to displaying y
values if an explicit labels arg is not provided, mirroring
the behaviour of the base text() function. (#501 1)tinyplot() generic in
preparation for tinyplot_add() is now more robust so that
it is compatible with do.call() again (reported by @FlorianSchwendinger). This is
achieved by inspecting the functions called rather than just their
names. (#504 @zeileis)by is logical. Thanks
to @TCornulier for
the report. (#512 1)legend passed as a
symbol through S3 methods (e.g., tinyplot.foo) would fail.
(#515 1)tinyplot_add(), should
now respect the x-axis order of the original plot layer. This should
ensure that we don’t end up with misaligned layers. For example, when
ribbon is added on top of an errorbar plot. (#517, #520, #523, #526
1)Add a “recession bars” section to the
Tips & tricks vignette. (#503 1)
Point out more explicitly how the draw argument is
evaluated within tinyplot() and that it thus has access to
the local definition to all variables such as x and
y etc. (#507 @zeileis)
cex argument (e.g., a continuous
variable from your dataset). Simultaneously enables dual-legend support
for combined size + color mappings. The updated
?type_points documentation contains several examples. (#433
1)tinyplot.default(), so that
tinyplot(x, type = "boxplot") and
tinyplot(~ x, type = "boxplot") essentially produce the
same output as boxplot(x). (#454 @zeileis)type_errorbar() and type_point_range() get
a dodge argument. (#461 @vincentarelbundock)tinyplot(..., theme = <theme>) argument
enables users to invoke ephemeral themes as an alternative to the
persistent themes that follow tinytheme(<theme>).
(#484 1)x/yaxl arguments allow for axes
label adjustment, users can now adjust the legend labels too with
tinyplot(..., legend = list(labeller = <labeller>)).
The labeller argument is passed to tinylabel;
see the latter’s help documentation for examples. (#488 1)tinyplot_add() now evaluates the additional call in the
environment from which tinyplot_add() is called so that it
also works in non-base environments such as in function definitions.
Additionally, the call matching is now more precise, matching only
tinyplot() or plt() or their fully-qualified
counterparts (with tinyplot:: prefix). Finally, the
internals where these calls are stored are streamlined, avoiding
modifying the user-visible options(). (#460 @zeileis)tinylabel bugs. (#468 1)
tinylabel(x, "%") is more precise, preserving unique
levels of x through automatic decimal level determination.
Thanks to @etiennebacher for the bug report in
#449.x/y variables, even if the plot type
internally coerces it to factor (e.g., "boxplot")type_text() can now also deal with factor
x/y variables by converting them to numeric
which helps to add text to barplots etc. (#470 @zeileis)tinytheme() bugs.
tinytheme()
calls now inherit the correct parameters and spacing. (#475, #481
1)cex theme settings are now reset correctly.
(#482 1)altdoc from Suggests to
Config/Needs/website. Thanks to @etiennebacher for the suggestion and
to @eddelbuettel
for help with the CI implementation.devcontainer.json file for remote testing. (#480
1)type_text() gains xpd and srt
arguments for controlling text clipping and rotation, respectively.
(#428 1)xlevels (in addition to ylevels) in
type_spineplot() for spine plots with categorical
x variable. (#431 @zeileis)plt_add(), to become
misaligned in faceted plots (#313). This also resolves a related
alignment + layering issue specific to the Positron IDE (positron#7316).
As an aside, tinyplot should now be fully compatible with
Positron. (#438 1)"p"-alike plot types (including "jitter")
if y is a factor or character.tinyplot behaves inside loops, particularly for themed
plots where only the final plot was being drawn in Quarto/RMarkdown
contexts. Special thanks to @hadley and @cderv for helping us debug. (#425 @vincentarelbundock)xlevels argument of type_barplot()
could not handle numeric indexes correctly. (#431 @zeileis)type_hline, type_vline,
type_abline) through better recycling logic. For example,
these types now work correctly across non-by facets.
Simultaneously, users can also call them in a base plot layer, relaxing
the requirement that they must be called as part of a subsequent plot
layer via tinyplot_add(). (#422 1)tinytheme("ridge") regression that was
accidentally introduced in v0.4.0, which was causing a palette mismatch
for gradient legends. (#415 1)"barplot" / type_barplot() for bar plots.
This closes out one of the last remaining canonical base plot types that
we wanted to provide a native tinyplot equivalent for.
(#305 and #360 @zeileis and 1)"violin" / type_violin() for violin plots.
(#354 1)tinyplot(..., file = "*.pdf") will now default to
using cairo_pdf() if cairo graphics are supported on the
user’s machine. This should help to ensure better fidelity of
(non-standard) fonts in PDFs. (#311 1)
The palette argument now accepts a vector or list of
manual colours, e.g.
tinyplot(..., palette = c("cyan4", "hotpink", "purple4")),
or
tinytheme("clean", palette = c("cyan4", "hotpink", "purple4"))
(#325 1)
Two new sets of top-level arguments allow for greater axis customization:
xaxb/yaxb control the manual break points
of the axis tick marks. (#400 1)xaxl/yaxl apply a formatting function to
change the appearance of the axis tick labels. (#363, #391 1) These
x/yaxb and x/yaxl arguments can be used in
complementary fashion; see the new (lower-level) tinylabel
function documentation. For example:tinyplot((0:10)/10, yaxb = c(.17, .33, .5, .67, .83), yaxl = "%")The x/ymin and x/ymax arguments can now
be specified directly via the tinyplot.formula() method
thanks to better NSE processing. For example, instead of having to
write
with(dat, tinyplot(x = x, y = y, by = by ymin = lwr, ymax = upr))users can now do
tinyplot(y ~ x | by, dat, ymin = lwr, ymax = upr)Underneath the hood, this works by processing these NSE arguments as
part of formula model.frame() and reference against the
provided dataset. We plan to extend the same logic to other top-level
formula arguments such as weights and subset
in a future version of tinyplot.
tinyplot(..., cex = <cex>) argument should be
respected when using type = "b". Thanks to @rjknell for report #307
and @vincentarelbundock for the
fix.tinyplot(..., lwd = <lwd>) argument is now
correctly passed down to pt.lwd for type "p",
which sets proper line weight for the border of pch symbols
in legend. Report in #319 and fix in #320 by @kscott-1.x and/or y as character variables
now triggers the same default plot type behaviour as factors,
e.g. boxplots. (#323 1)type_points()/"p") now work
even if x or y is a factor or character
variable. (#323 1)tinyplot(..., col = <col>) argument now
accepts a numeric index. (#330 1)type_text() now accepts non-character labels. (#336
1)tinyplot(..., pch = <pch>) argument now
accepts character literals, e.g. pch = ".". (#338 1)type_lines()/"l") now pass on
the bg argument to the drawing function. Thanks to @wviechtb for report in
#355 (@zeileis)."boxplot" and "jitter" types. Thanks to @eddelbuettel for the
report in #357 (1).las = 2 or
las = 3. (#369 1)plt_add() on a faceted plot, but this appears to be an
upstream limitation/bug positron#7316."p"-alike plot types (including "jitter")
if y is a factor or character. (#387 1)palette and col arguments, particularly with
respect to recycling behaviour. Thanks to @eddelbuettel for the report (#352) and
1 for the fix (#410).altdoc fix)tinyplot v0.3.0 is a big release with many new features, both internal and user-facing. Related updates are grouped below for easier navigation.
type logic and functional equivalents(Primary PR and author: #222 @vincentarelbundock)
In addition to the standard character labels ("p",
"density", etc.), the type argument now
supports functional equivalents (type_points(),
type_density(), etc.). These new functional types all take
the form type_*().
The character and functional types are interchangeable. For example,
tinyplot(Nile, type = "hist")and
tinyplot(Nile, type = type_hist())produce exactly the same result.
The main advantage of the functional type_*()
variants is that they offer much more flexibility and control beyond the
default case(s). Users can pass appropriate arguments to existing types
for customization and can even define their own
type_<typename>() functions. More information is
available in the dedicated help page for each type (e.g.,
?type_hist, ?type_lm, etc.)
On the development side, overhauling the type system
has also allowed us to introduce a number of new plot types and features
(see list below). We have also simplified our internal codebase, since
explicit argument passing requires less guesswork on our end. Speaking
of which, we now recommended that users explicitly pass ancillary
type-specific arguments as part of the relevant type_*()
call. For example,
tinyplot(Nile, type = type_hist(breaks = 30))is preferable to
tinyplot(Nile, type = "hist", breaks = 30)While the latter option will still work, we cannot guarantee that
argument passing will work in every situation. (Reason: Passing
ancillary type-specific arguments at the top level of the plot call only
works if these do not conflict with the main arguments of the
tinyplot() function itself; see #267.)
Some minor breaking changes were unavoidable; see further below.
For more details on the new type system, please see
the dedicated Plot
types vignette on the website.
Visualizations:
type_spineplot() (shortcut: "spineplot")
spine plots and spinograms. These are modified versions of a histogram
or mosaic plot, and are particularly useful for visualizing factor
variables. (#233 @zeileis with contributions from 1)type_qq() (shortcut: “qq”) for quantile-quantile plots.
(#251
@vincentarelbundock)type_ridge() (shortcut: "ridge") for ridge
plots aka Joy plots. (#252 @vincentarelbundock, @zeileis, and 1)type_rug() (shortcut: "rug") adds a rug to
an existing plot. (#276
type_text() (shortcut: "text") adds text
annotations. (@vincentarelbundock)Models:
type_glm() (shortcut: "glm") (@vincentarelbundock)type_lm() (shortcut: "lm") (@vincentarelbundock)type_loess() (shortcut: "loess") (@vincentarelbundock)type_spline() (shortcut: "spline") (#241
1)Functions:
type_abline(): line(s) with intercept and slope (#249
@vincentarelbundock)type_hline(): horizontal line(s) (#249 @vincentarelbundock)type_vline(): vertical line(s) (#249 @vincentarelbundock)type_function(): arbitrary function. (#250 @vincentarelbundock)type_summary(): summarize values of y
along unique values of x (#274
(Primary PR and authors: #258 @vincentarelbundock and 1)
tinytheme() function provides a convenient
mechanism for styling plots according to a variety of pre-defined
themes, e.g. tinytheme("clean").tinytheme()
(with no argument) to restore the default plot aesthetic.tinytheme() sets a hook for a group
graphical parameters by passing them through tpar(). Users
can still use tpar() to style their plots manually by
setting individual graphical parameters. But going forward we expect
that most tinyplot users will prefer the convenience of
going through tinytheme().tinyplot() arguments:
flip <logical> allows for easily flipping
(swapping) the orientation of the x and y axes. This should work
regardless of plot type, e.g.
tinyplot(~Sepal.Length | Species, data = iris, type = "density", flip = TRUE).
(#216 1)draw = <draw_funcs> allows users to pass
arbitrary drawing functions that are evaluated as-is, before the main
plotting elements. A core use case is drawing common annotations across
every facet of a faceted plot, e.g. text or threshold lines. (#245
1)facet.args gains a free = <logical>
sub-argument for independently scaling the axes limits of individual
facets. (#253 1)tpar() gains additional grid.col,
grid.lty, and grid.lwd arguments for
fine-grained control over the appearance of the default panel grid when
tinyplot(..., grid = TRUE) is called. (#237 1)tinyplot_add() (alias: plt_add())
convenience function allows easy layering of plots without having to
specify repeat arguments. (#246
@vincentarelbundock)type_density(joint.bw = <option>) argument. See the
function documentation for details. (#291 1 and @zeileis)tinyplot.density() method). Instead,
please rather call tinyplot(..., type = "density") or
tinyplot(..., type = type_density()) on the raw data and
pass grouping or facet arguments as needed. (#284 1)ribbon.alpha argument in tinyplot()
has been deprecated. Use the alpha argument in
type_ribbon() (and equivalents) instead: e.g.,
tinyplot(..., type = type_ribbon(alpha = 0.5)).
tinyplot(..., type = "ribbon", alpha = 0.5) because the
latter matches the top-level alpha argument of
tinyplot() itself (and thus modifies the entire
palette, rather than just the ribbon). See our warning
about passing ancillary type-specific arguments above.plt(numeric ~ character) now work
correctly, with the character variable automatically being coerced to a
factor. (#219 @zeileis)xlim and ylim when explicitly
supplied by the user. (Thanks to @mclements for code submission #221)ymin or ymax args,
now inherit these values from y (#224 1)y is a factor now work automatically,
dispatching to the new type_spineplot() type. Thanks to
@zeileis for the
original suggestion all the way back in #2 and the eventual solution in
#233.type_histogram(free.breaks = <logical>, drop.zeros = <logical>)
arguments enable fine-grained control over this behaviour. (#228 @eleuven and
?type_hist,
type_ridge, etc.)New Features:
The axes argument of
tinyplot()/plt() gains extra options for
fine-grained control of the plot axes. In addition to the existing
logical (TRUE/FALSE) option, users can now
specify one of the following character keywords (or, just their first
letters as a convenient shorthand):
"standard" (with axis, ticks, and labels; equivalent to
TRUE),"none" (no axes; equivalent to
FALSE),"ticks" (only ticks and labels without axis line),"labels" (only labels without ticks and axis
line),"axis" (only axis line and labels but no ticks).Simultaneously, the main plotting functions also gain the
xaxt and yaxt for separately
controlling the two axes using the same keyword options. For example,
plt(0:10, xaxt = "l", yaxt = "t") will yield a plot where
the x-axis only contains labels and the y-axis contains both labels and
ticks, but no axis line. (#190 @zeileis)
Support additional boxplot arguments like varwidth,
notch, etc. Note that
tinyplot(..., type = "boxplot", boxwidth = <num>) is
equivalent to the boxplot(..., width = <num>); we
just use the “box(width)” prefix to avoid conflicting with the existing
tinyplot(..., width) argument. (#196 1)
Bug fixes:
type = "density",
which was a regression accidentally introduced in v0.2.0 (#187 1)x ==
by, or these two are functionally identical. (#196 1)xlab and ylab arguments not respected in
some plots. Thanks to @lbelzile for reporting Issue #203.tinyplot(log(x) ~ x). (#197 @zeileis)tinyplot(mpg ~ wt, data = mtcars, facet = am + vs ~ gear))
now plot all panels correctly, even if some combinations are missing.
(#197
Internals:
New features:
type = "n", i.e. empty plot. Since
type = "n" implicitly assumes points, which limits the type
of legend that can be drawn alongside the empty plot, we have also added
a companion empty argument that can be used alongside any
plot type. (#157, #167 1)type = "boxplot". Simultaneously enables
plt(numeric ~ factor) support, first raised in #2, so that
a boxplot is automatically plotted if a numeric is plotted against a
factor. (#154 1)type = "polypath". (#159 1)type = "rect". (#161 1)type = "segments". (#163 1)type = "histogram" (alias type = "hist").
(#164 1)type = "jitter" (alias type = "j"). (#170
1)Internals:
Misc:
Our first CRAN submission! This v0.1.0 release includes the following new features and updates:
License:
Breaking changes:
tinyplot() function arguments, the following two arguments
have been renamed (old => new):
par_restore => restore.par (note the
change in word order too!)ribbon_alpha => ribbon.alpha We don’t
believe that these two arguments are much used in practice. So hopefully
it will only have a negligible effect on existing tinyplot
code in the wild, even though it is a breaking change. (#149 1)New features:
by. Thanks to @zeileis for detailed feedback and advice
around the default palette choice (a restricted version of the “viridis”
palette), as well as StackOverflow user mnel, whose answer here provided the
inspiration for the final implementation. (#122 1)lwd argument for adjusting line widths.
Similar to pch, lty, etc. this arguments also
accepts a “by” convenience keyword to automatically vary line widths by
group. (#134 1)tpar() now accepts standard par()
arguments in addition to the tinyplot-specific ones. This
allows users to set or query graphical parameters via a single
convenience function, instead having to invoke tpar and
par separately. (#140 1)
tpar() has gained some additional
parameters for fine-grained control of global plot defaults, including
grid, ribbon.alpha, and various
file.* parameters (see next bullet point).file argument, alongside corresponding width
and height arguments for output customization (both of
which are defined in inches). For example,
tinyplot(..., file = "~/myplot.png", width = 8, height = 5).
This implementation relies on a simple internal wrapper around the
traditional R external graphics devices like png(),
pdf(), etc. But it may prove more convenient, since the
current global graphics parameters held in (t)par() are
carried over to the external device too and don’t need to be reset. Note
that the appropriate device type is determined automatically by the file
extension, which must be one of “.png”, “.jpg” (“.jpeg”), “.pdf”, or
“.svg”. (#143 1)tinyplot logo. (#148 1)get_saved_par() function can be used to
retrieve the par settings from immediately before or
immediately after the preceding tinyplot call. This
function replaces some older (non-exported) internal functions that
tinyplot was using to restore and control par
environments. But it could also prove help to end users who are looking
for additional ways to restore par settings after the fact.
See ?get_saved_par for some examples. (#152
tinyplot/plt gains a new
alpha = <numeric[0,1]> convenience argument for
adding transparency to plot elements and colours. Example use:
plt(rnorm(1e3), pch = 19, alpha = 0.3). (#129 1)bg (or its alias,
fill) a numeric in the range [0,1]. This
feature has the same effect as bg = "by" except for the
added transparency. Example use:
tinyplot(lat ~ long | depth, data = quakes, pch = 21, cex = 2, bg = 0.2).
(#129
Bug fixes:
tpar(facet.x = ...) args from
being passed forward and set correctly. (#137 1)type = "density". (#147
Internals:
tinyplot website. (#135 1)inst/tinytest is
pushing the install tarball over CRAN’s recommended 5 MB limit. Please
note that local testing of the package requires adding the
NOT_CRAN=TRUE environment variable to your .Renviron file
(or, exporting it in your .bashrc/.zshrc/etc. dotfile if you prefer that
approach). (#145 @vincentarelbundock & 1)density grid coords. (#150 1)IMPORTANT BREAKING CHANGE:
The package has been renamed to tinyplot. (#22 1)
This package renaming also incorporates the following function changes:
plot2() is replaced by tinyplot() (or its
shorthand alias plt()).par2() is replaced by tpar().So, where you used to write…
library(plot2)
plot2(Sepal.Length ~ Petal.Length | Species, iris)… you should now write:
library(tinyplot)
tinyplot(Sepal.Length ~ Petal.Length | Species, iris)
# Or, use the equivalent shorthand `plt` alias
plt(Sepal.Length ~ Petal.Length | Species, iris)The package URLs have been updated accordingly:
Many thanks to everyone who provided thoughtful feedback about this prospective name change, especially @zeileis and @vincentarelbundock for kicking off the discussion, as well as the 100+ participants who voted in the social media poll.
For more details about the rational underlying this renaming decision, please see the following GitHub comment, as well as the discussion that preceded it: https://github.com/grantmcdermott/plot2/issues/22#issuecomment-1928472754
Website:
We now have a dedicated website! (#80 @vincentarelbundock)
New features:
cex and bg (alias
fill) arguments. The latter also permit the “by”
convenience keyword similar to lty and pch.
This is useful for plotting filled point characters (e.g., pch = 21),
where you want a different colour for the fill and border. (#50, #75
1)add argument allows new plot2 objects to be
added to / on top of the existing plot window. (#60 1)plot2(~ Temp | Month, airquality). (#62 1 and @zeileis)plot2(x, type = "density") as an
alternative to plot2(density(x)). Works for both the atomic
and one-sided formula methods. (#66 1)plot2 gains a new facet argument for
drawing faceted plots. Users can override the default square arrangement
by passing the desired number of facet rows or columns to the companion
facet.args helper function. Facets can be combined with
by grouping, or used on their own. (#83, #91, #94, #96,
#101, #103 1)plot2-specific graphical
parameters globally via the new par2() function (which is
modeled on the base par() function). At the moment only a
subset of global parameters, mostly related to legend and facet
behaviour, are exposed in par2. But users can expect that
more will be added in future releases. (#33, #94 1)Bug fixes:
plot2(rnorm(100)). (#52 etiennebacher)lmar and
fmar arguments of par2(). The default legend
margin is par2(lmar = c(1,0, 0.1), which means that there
is 1.0 line of padding between the legend and the plot region (inside
margin) and 0.1 line of padding between the legend and edge of the
graphics device (outer margin). Similarly, the default facet padding is
par2(fmar = c(1,1,1,1), which means that there is a single
line of padding around each side of the individual facets. Users can
override these defaults by passing numeric vectors of the appropriate
length to par2(). For example,
par2(lmar = c(0,0.1) would shrink the inner gap between the
legend and plot region to zero, but leave the small outer gap to outside
of the graphics device unchanged. (#94 1)Breaking changes:
palette
argument that unifies the old palette and (deprecated)
palette.args arguments. In addition, the default palette
for small groups has been changed from “Okabe-Ito” to “R4”. (#31 and #32
1)legend argument
that unifies the previous (deprecated) legend.position and
legend.args arguments. This change also enables several
enhancements over the old legend behaviour; see below. (#34 1)New features:
log. (#15 @etiennebacher)pch and lty arguments now accept
a “by” convenience keyword for automatically adjusting plot characters
and line types by groups. (#28
legend argument, including changing labels, turning of the
legend title, and so on. (#34 1)"pointrange", "errobar",
and "ribbon" plot types. (#35 @vincentarelbundock, #40 and #46
1)grid = TRUE as an alternative to
grid = grid(). (#43
Bug fixes:
par(pch=X) globally is now respected. (#20
1)palette("ggplot2") is
now respected. (#44
Breaking changes:
New features:
pch, lty,
and col types per group (#5 and #11 by @vincentarelbundock).Bug fixes:
plot2 now works (#13 by 1,
thanks @karoliskoncevicius for
reporting).Internals:
plot2.formula (#8 by @zeileis).Project: