library(tinyplot)
= 50000
n = rnorm(n)
x = x + rnorm(n)
y = sample(c("a", "b"), n, replace = TRUE)
z = data.frame(x, y, z)
dat tinyplot(y ~ x | z, data = dat, alpha = .1, pch = 19)
Tips & Tricks
This page collects miscellaneous tips and tricks for tinyplot. By definition, these are workarounds—i.e., techniques that fall outside of standard use cases or features that aren’t (yet) natively supported by the package. Please feel free to suggest or add more tips via our GitHub repo.
Legend
Opacity (alpha
)
By default, the legend inherits the opacity of the plotted elements. In some cases, this may be undesirable. For example, in the following plot, the legend is too light:
One solution is to draw our plot in two steps. First, we draw an empty plot with the desired (zero transparency) legend. Second, we add the transparent points on top of the existing canvas.
tinyplot(y ~ x | z, data = dat, pch = 19, empty = TRUE)
tinyplot_add(empty = FALSE, alpha = .1)
Labels
Direct labels
Direct labels can provide a nice alternative to a standard legend, particularly for grouped line plots. While tinyplot
doesn’t offer a “native” direct labels type, you can easily achieve the same end result using an idiomatic layering approach.
library(tinyplot)
tinytheme("clean2")
= airquality
aq $Month = factor(month.name[aq$Month], levels = month.name[5:9])
aq
# base layer
plt(Temp ~ Day | Month, data = aq, type = "l", legend = FALSE)
# for labels: subset to final dates for each month
= aq[aq$Day == ave(aq$Day, aq$Month, FUN = max), ]
aq2
# add the labels with a type_text() layer
plt_add(data = aq2, type = "text", labels = aq2$Month,
pos = 4, offset = 0.2, xpd = NA)
Hmmmm, can you see a problem? We used type_text(..., xpd = NA)
in the second layer to avoid text clipping, but the longer labels are still being cut off due to the limited RHS margin space of our "clean2"
plotting theme.
The good news is that there’s an easy solution. Simply grab the theme’s parameters, bump out the RHS margin by the longest label in our dataset, and then replot.
# Fix: first grab the theme params and then adjust the RHS margin by
# the longest label in the dataset
= max(strwidth(as.character(aq2$Month)))/2 # divide by 2 to get lines
longest_lab = tinyplot:::theme_clean2
parms $mar[4] = parms$mar[4] + longest_lab
parmstinytheme("clean2", mar = parms$mar) # theme with adjusted margins
# Now plot both the base and direct label layers
plt(Temp ~ Day | Month, data = aq, type = "l", legend = FALSE)
plt_add(data = aq2, type = "text", labels = aq2$Month,
pos = 4, offset = 0.2, xpd = NA)
# Reset the theme (optional, but recommended)
tinytheme()
Rotated axis labels
When category labels are long or overlapping, users may want to rotate them for readability. One option is fully perpendicular (90°) axis labels, which tinyplot
supports via themes, e.g. tinytheme("clean", las = 2)
. If a user wants finer control over the degree of rotation—say, 45°—this requires a bit more manual effort since we do not support custom rotation out of the box. The workaround involves three steps:
- Suppress the default x-axis with
xaxt = "n"
. - Use
text()
to manually add rotated labels. - Optionally, clear the y-axis label by setting
ylab = ""
.
library(tinyplot)
tinyplot(~cyl, data = mtcars, type = "barplot", xaxt = "n", ylab = "")
text(1:3, 0,
labels = c("Four cylinders", "Six cylinders", "Eight cylinders"),
srt = 45, # rotate text 45 degrees
adj = c(1.1, 1.5), # adjust text alignment
xpd = TRUE) # allow drawing outside plot region
Note that adj
and xpd
settings may require trial and error to position labels correctly. Also, removing the x-axis label by setting ylab = ""
is unintuitive but currently necessary when using formulas like ~ cyl
.
P.S. Another option for long axis labels is to wrap them at a designated character length. See the final example in the tinylabel
documentation for an example.