Sign in

Grant McDermott

@gmcd.bsky.social
5.2K followers 182 following 765 posts

Economics and data science | Former academic now working in the tech sector | Views my own | 🇿🇦 in 🇺🇸 | grantmcdermott.com

PostsRepliesMedia
Grant McDermott @gmcd.bsky.social · 28/09/2026
Lines can now be coloured by a continuous variable; nice for plotting time-dependent trajectories. Separately, a new `tinyplot.array()` method plots multidimensional arrays directly. grantmcdermott.com/tinyplot/man/tinyplot.array.html
Lorenz attractor with the line coloured by time. Code: https://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/line-lorenz.RHip vs knee angle through the gait cycle for nine boys, coloured by time, from a 3D array.
Code:
gait9 = gait[, 1:9, ]
plt(gait9, draw = plt(gait9, col = "lightgray", facet = FALSE, add = TRUE))
130
Grant McDermott @gmcd.bsky.social · 28/09/2026
Order categories on the fly (e.g., by ascending or descending sort), no prior factor leveling required. Unrelated, but nice to demo with these examples... we finally have support for a long-standing FR: rotate tick labels by _any_ angle. grantmcdermott.com/tinyplot/man/type_barplot.htm
Bar chart of mean chick weight by feed, sorted in descending order with rotated labels. Code: plt(weight ~ feed, data = chickwts, type = type_barplot(xord = "desc", fun = mean), xaxr = 45)The same bar chart sorted in ascending order. Code: plt(weight ~ feed, data = chickwts, type = type_barplot(xord = "asc", fun = mean), xaxr = 45)
100
Grant McDermott @gmcd.bsky.social · 28/09/2026
Finer control over facets: custom titles via `prefix`, `labeller` & `sep`, outer-only axes, and dropping empty facets or unused categories. Plus new tools for axis labels, including dictionary-based relabeling, e.g. `xaxl = c(wt = "Weight")`. grantmcdermott.com/tinyplot/man/tinyplot.htm
Faceted scatter plot of mpg vs weight, with custom facet titles and outer-only axes. Code: plt(mpg ~ wt | factor(cyl), facet = ~ am + vs, data = mt, facet.args = list(prefix = c(vs = "V-shaped", am = "Trans."), sep = "\n", axes = "outer")Coefficient plot with tick labels relabelled via a named dictionary. Code: plt(est ~ term, ymin = lwr, ymax = upr, data = coefs, type = "pointrange", xaxl = c(wt = "Weight\n(1,000 lbs)", hp = "Horsepower", ...))
100
Grant McDermott @gmcd.bsky.social · 28/09/2026
New plot types: tiles & heatmaps, sina plots, hexbins (see above), and stacked areas. grantmcdermott.com/tinyplot/vignettes/types.html
Correlation matrix of the attitude dataset drawn as labelled tiles. Code: plt(Var1 ~ Var2 | Correlation, data = catt, type = "tile", col = "white", ylim = "rev"); plt_add(type = "text", labels = round(catt$Correlation, 2))Sina points layered on violins, showing penguin bill lengths by species. Code: plt(bill_len ~ species | species, data = penguins, type = "violin", alpha = 0.5, theme = "clean"); plt_add(type = "sina", alpha = 0.3
100
Grant McDermott @gmcd.bsky.social · 28/09/2026
𝐭𝐢𝐧𝐲𝐩𝐥𝐨𝐭 v0.8.0 now available on CRAN 🎉 grantmcdermott.com/tinyplot/ This is another big release: new plot types, finer facet & axis control, smarter handling of categorical data, and lots more. Same tiny footprint, though. Short highlight thread below 🧵 #rstats
Heatmap of the mtcars dataset, scaled within each column. Code: https://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/heatmap-mtcars.RHistogram of New York temperatures, with bars coloured by their own x values. Code: plt(~ Temp | Temp, data = airquality, type = "hist", theme = "classic")Hexbin plot of 20,000 bivariate normal draws. Code: https://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/hexbin.RStacked area plot of telephones in use by world region, 1956-1961. Code: plt(WorldPhones[-1, ], type = type_area(stack = TRUE, byord = "end"))
13513
Grant McDermott @gmcd.bsky.social · 05/09/2026
With that done, time to read my youngest a delightful allegory about the Springbok scrum and maul.
050
Grant McDermott @gmcd.bsky.social · 31/07/2026
Would appreciate some #rstats feedback on a potential `tinyplot` change: github.com/grantmcdermo... Should we default to suppressing the (redundant) inner axes for faceted plots? We already do this for themes without a plot frame (box). But I'm thinking of enabling for framed plots too. #dataviz
Faceted tinyplot where the same axes are displayed for all sub plots.Same plot as before, except the redundant inner axes are now suppressed.
662
Grant McDermott @gmcd.bsky.social · 07/07/2026
Get on the phone. There are only two men for the job.
NBC rugby pundits, Alex Corbisiero and Dan Kyle, inexplicitly in the same room rather than Skyping from their kitchens.
100
Grant McDermott @gmcd.bsky.social · 03/07/2026
5. There are a bunch of other improvements... from "smart" axis limits to caption support to numerous bug fixes... See our full v0.7.0. changelog for details: grantmcdermott.com/tinyplot/NEW... Thanks to everyone who contributed, made suggestions, or filed bug requests. Happy tinyplotting!
https://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/polygon-valentine.R
061
Grant McDermott @gmcd.bsky.social · 03/07/2026
4. We've added `tinyplot.*` methods for core R objects (data.frame, matrix, ts), making it trivial to visualize your data quickly, e.g. grantmcdermott.com/tinyplot/man... Bonus: this all means you can use tinyplot with pipes, e.g. `mydata |> plt(y ~ x | group)`. grantmcdermott.com/tinyplot/man...
tinyplot(iris, by = "Species", frames = TRUE)tinyplot(EuStockMarkets,
         facet.args = NULL,
         type = "area", xlab = NA, yaxl = ",",
         main = "European stock indices")
181
Grant McDermott @gmcd.bsky.social · 03/07/2026
3. Support for direct legends and (automatic) text repelling, e.g. grantmcdermott.com/tinyplot/man...
https://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/direct-labels-aq.Rhttps://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/line-ipcc.R
140
Grant McDermott @gmcd.bsky.social · 03/07/2026
2. We've added more plot types and improved the functionality of existing types. grantmcdermott.com/tinyplot/vig...
https://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/likert.Rhttps://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/ellipse-penguins.R
141
Grant McDermott @gmcd.bsky.social · 03/07/2026
1. We've significantly refactored (and added to) our theming capabilities. Choose from 20+ built-in themes... or roll your own. grantmcdermott.com/tinyplot/vig...
https://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/add-text-mtcars.Rhttps://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/pirate-iris.R
151
Grant McDermott @gmcd.bsky.social · 03/07/2026
𝐭𝐢𝐧𝐲𝐩𝐥𝐨𝐭 v0.7.0 now available on CRAN 🎉 This is big release, with loads of new features. Same tiny footprint, though ;-) Short highlight thread below, borrowing examples from our gallery: grantmcdermott.com/tinyplot/vig...
https://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/bubble-quakes.Rhttps://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/simpsons-paradox.Rhttps://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/barplot-meat.Rhttps://github.com/grantmcdermott/tinyplot/blob/main/vignettes/gallery_figs/spineplot-titanic.R
48726
Grant McDermott @gmcd.bsky.social · 20/05/2026
Sometimes, it's the little things.
Grouped line (tiny)plot with direct labels.
0101
Grant McDermott @gmcd.bsky.social · 20/05/2026
github.com/grantmcdermo... 👀
Merged PR
120
Grant McDermott @gmcd.bsky.social · 29/04/2026
Happy to see that `jgd` is now up on CRAN. An alternative #rstats graphics device that's fast and lightweight (mostly pure C). Try it out with our VS Code extension or Deno server. More details: github.com/grantmcdermo... Joint work with the indefatigable @eitsupi.bsky.social.
2396
Grant McDermott @gmcd.bsky.social · 01/04/2026
5. Last but not least, we've been chipping away at `jgd`, a novel + lightweight #rstats graphics device. My original motivation was simply better graphics support in VS Code, but @eitsupi.bsky.social has pushed it much further. CRAN submission imminent. Try it out. github.com/grantmcdermo...
071
Grant McDermott @gmcd.bsky.social · 01/04/2026
1. `tinyplot` v0.6.1 is out on CRAN. This release contains mostly bug fixes and internal optimizations. grantmcdermott.com/tinyplot/NEW... Who knew that base #rstats plotting could be this easy and feature-rich? P.S. Check out @zeileis.org's nice slides here: www.zeileis.org/papers/Psych...
tinyplot boxplot with jittered points
1195
Grant McDermott @gmcd.bsky.social · 20/02/2026
I think the main issue is that many people, quite reasonably tbf, don't like the default base data.frame print method... But this is easy to override! gist.github.com/grantmcdermo...
A nicer print.data.frame method showing column types, as well as a subset of rows. Inspired by data.table's print method.
0195
Grant McDermott @gmcd.bsky.social · 28/01/2026
ICYMI with a quick screenshot as sales pitch. Simply feed your estimation a bunch of .parquet files on disk and run it as normal. This example takes 180m rows of NYC taxi data and computes the model in < 1 second. On a laptop.
dbreg example showing how to estimate a model against a large dataset, comprising parquet files on disk. The model takes < 1 to run, including the time needed to read the data from disk.

dbreg(
   tip_amount ~ fare_amount + passenger_count | month + vendor_name,
   path     = "read_parquet('nyc-taxi/**/*.parquet')",
   vcov     = ~month,    # clustered SEs
   strategy = "compress" # skip auto strategy overhead
)
2367
Grant McDermott @gmcd.bsky.social · 26/01/2026
New features include: - fast binscatter regression on a database backend - new acceleration strategies - analytical clustered SEs - interaction terms support - stats methods (predict, vcov, etc.) - integration with tabling sw - etc. Full v0.0.3 changelog: grantmcdermott.com/dbreg/NEWS.h... [2/2]
A simple dbbinsreg example from the dbreg package.

# Accounting for Diet "fixed effects" helps to resolve the situation
# (We'll also add a line and change the theme for a nicer plot)
dbbinsreg(weight ~ Time | Diet, data = ChickWeight, nbins = 10, cb = TRUE,
          line = c(1, 1), theme = "clean")
140
Grant McDermott @gmcd.bsky.social · 20/01/2026
Stage three of four complete for the corner potting shed / bus stop. Main workbench shelf up next. (Full credit to my mate Mike for the complicated roof joins and structure. I'm just the willing labour.)
WIP potting shed / structure.
020
Grant McDermott @gmcd.bsky.social · 20/01/2026
With the fine weather this MLKD weekend, I took the opportunity to do something economically useful: digging holes and filling them back up again.
A post in hole Same post and hole, now filled with concrete
230
Grant McDermott @gmcd.bsky.social · 18/01/2026
Amen. So many observations resonated for me, especially this one. Thanks for sharing. I would add one more category. The flip side to maintainer burden is a _duty of care for your users_.
It’s super impressive that agents were able to bootstrap a browser in a week! But holy crap! I hope nobody ever uses that thing or would try to build an actual browser out of it, at least with this generation of agents, it’s still pure slop with little oversight. It’s an impressive research and tech demo, not an approach to building software people should use. At least not yet
120
Grant McDermott @gmcd.bsky.social · 14/01/2026
Me, reading LinkedIn posts.
Brandolini's law: The amount of energy needed to refute bullshit is an order of magnitude bigger than that needed to produce it.
2405
Grant McDermott @gmcd.bsky.social · 06/12/2025
If you see this, repost with your model of positive masculinity.
Bandit. The dad we all want to be when we grow up.
1112
Grant McDermott @gmcd.bsky.social · 29/11/2025
Hearts on the vine?
A houseplant casts a shadow of heart-shaped climbers in the background
050
Grant McDermott @gmcd.bsky.social · 27/11/2025
Happy `tinyplot` v0.6.0 (codename "Thanksgiving") release day to all those that celebrate. Some new features, but mostly bug fixes and internal improvements. grantmcdermott.com/tinyplot/NEW... #rstats
Example of dodged pointrange (tiny)plot, with aligned ribbons layered on top.
1256
Grant McDermott @gmcd.bsky.social · 08/11/2025
The non rugby mind cannot comprehend these two images.
A bloodied Damian McKenzie lining up a matching winning penalty against ScotlandSmile before the kick
151
Grant McDermott @gmcd.bsky.social · 30/09/2025
Successfully nerdsniped myself into writing a little script for this. gist.github.com/grantmcdermo... (Longer than it probably needs to be bc of annoying Wiki table formatting, but I'm too lazy to find another source.)
Showing the minimum no. of voters that could have flipped the results from recent US presidential elections.

elec_marg(2016)
#> Winner: Republican 
#> Min votes to flip Democratic: 77,744
#>   0.06% of total votes
#>   0.6% of votes from 3 states (Michigan, Pennsylvania, Wisconsin)

elec_marg(2020)
#> Winner: Democratic 
#> Min votes to flip Republican: 123,473
#>   0.08% of total votes
#>   0.7% of votes from 4 states (Georgia, Arizona, Wisconsin, Pennsylvania)

elec_marg(2024)
#> Winner: Republican 
#> Min votes to flip Democratic: 344,866
#>   0.2% of total votes
#>   2% of votes from 4 states (Wisconsin, Michigan, Pennsylvania, Georgia)
Comment
020
Grant McDermott @gmcd.bsky.social · 28/09/2025
Rinse and repeat.
090
Grant McDermott @gmcd.bsky.social · 28/09/2025
Clearly not the most important news coming out of Oregon tonight, but I just added a recession bars example to the tinyplot “Tips & tricks” vignette. grantmcdermott.com/tinyplot/vig... #rstats
tinyplot showing US GDP since 1980 with recessions highlighted in the background
1244
Grant McDermott @gmcd.bsky.social · 23/09/2025
`tinyplot` 0.5.0 is now available from CRAN & R-universe. Alongside bug fixes & internal improvements, this release includes some cool new features like bubble chart + dual legend support, element dodging, & ephemeral themes. Detailed changelog: grantmcdermott.com/tinyplot/NEW... #rstats #dataviz
tinyplot bubble chart example with dual legend, using penguins data. Taken from https://grantmcdermott.com/tinyplot/vignettes/gallery.html
15713
Grant McDermott @gmcd.bsky.social · 19/09/2025
Update: it won't see us through the winter, but a respectable harvest through the season.
Smorgasbord, of sorts. (A bunch of veg.)
070
Grant McDermott @gmcd.bsky.social · 19/09/2025
Word. Whenever someone asks me for career advice these days, I reply without irony: "Work on your core."
"Whoever designed the human visual system has a lot to answer for. Maybe not as much as the knee team, or the lower back group. But a lot." Quote from @kjhealy.co
051
Grant McDermott @gmcd.bsky.social · 25/08/2025
To borrow another example, taken from the `dbreg` README: github.com/grantmcdermo... Here I am running a fixed-effects regression on 180 million(!) row parquet dataset... and it completes **< 2 seconds**... on my laptop 🤯 This is powered by @duckdb.org under the hood. #rstats #econsky
Running dbreg::dbreg() on a full year of NYC taxi data... and it takes less than 2 seconds.

dbreg(
   tip_amount ~ fare_amount + passenger_count | month + vendor_name,
   path = "read_parquet('nyc-taxi/**/*.parquet')", ## path to hive-partitioned dataset
   vcov = "hc1"
)
#> [dbreg] Estimating compression ratio...
#> [dbreg] Data has 178,544,324 rows and 24 unique FE groups.
#> [dbreg] Using strategy: compress
#> [dbreg] Executing compress strategy SQL
#> 
#> Compressed OLS estimation, Dep. Var.: tip_amount 
#> Observations.: 178,544,324 (original) | 70,782 (compressed)
#> Standard Errors: Heteroskedasticity-robust
#>                  Estimate Std. Error  t value  Pr(>|t|)    
#> fare_amount      0.106744   0.000068 1564.742 < 2.2e-16 ***
#> passenger_count -0.029086   0.000106 -273.866 < 2.2e-16 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
38322
Grant McDermott @gmcd.bsky.social · 18/08/2025
#rstats Seen over at Mastodon: the `terminalgraphics` 📦 let's you render R plots _directly_ in a terminal window (e.g., R process launched from the command line, neovim or emacs). codeberg.org/djvanderlaan... Get it: `remotes::install_git(url = "codeberg.org/djvanderlaan/terminalg…
Screenshot of a `tinyplot` figure displayed directly in an R console (launched from the terminal), thanks to the new `terminalgraphics` package.
2447
Grant McDermott @gmcd.bsky.social · 03/08/2025
I don't think non-uniformity was the issue. Rather Frank doesn't like the default spacing of base graphics, esp. around the axis text and plot extent... But we offer much nicer spacing via themes; c.f. the reduction in whitespace in the rhs plot. (This is automated, but can be further customized.)
Comparing the spacing of the same tinyplot without and without themes.
100
Grant McDermott @gmcd.bsky.social · 03/08/2025
Sounds like you're looking for `tinyplot_add` (alias: `plt_add`)? grantmcdermott.com/tinyplot/man...
plt(wageinc ~ age | gender, data=svcensus, type='lm')
plt_add(type='p', alpha = 0.1)
100
Grant McDermott @gmcd.bsky.social · 03/08/2025
Jumping across threads, but this should definitely work. As you said elsewhere maybe a conflict with the redundant with()?
tinyplot lm type without SE bands.
200
Grant McDermott @gmcd.bsky.social · 18/07/2025
In other news, <Operation Autarky> in full swing here in the Willamette Valley. More "Dig for Idiocracy" than "Dig for Victory", but needs must.
Raised garden beds
020
Grant McDermott @gmcd.bsky.social · 18/07/2025
#rstats #econsky PSA: The next release of `fixest` will include some important changes (plus cool new features). E.g. Fixed-effects regs will now default to 'iid' SEs rather than clustered. github.com/lrberge/fixe... You can install and test drive the dev version from R-universe; see the README.
From the fixest NEWS file: the new default VCOV is iid for all estimations. To change the default to the way it was, place setFixest_vcov(all = "cluster", no_FE = "iid") in your .Rprofile.
13111
Grant McDermott @gmcd.bsky.social · 18/07/2025
Thanks for the post and test! I think you probably want barplots instead of histograms here, though? grantmcdermott.com/tinyplot/man... E.g., your final plot would be:
100
Grant McDermott @gmcd.bsky.social · 13/07/2025
I feel like @f2harrell.bsky.social brings this up with every tinyplot release notice... and we always respond by saying that themes are there to specifically reduce whitespace 🤷 grantmcdermott.com/tinyplot/vig...
110
Grant McDermott @gmcd.bsky.social · 12/07/2025
Also includes a mini update to the "Tips & tricks" vignette: how to add direct labels to a grouped line (tiny)plot. grantmcdermott.com/tinyplot/vig...
Grouped line plot with direct labels
061
Grant McDermott @gmcd.bsky.social · 10/06/2025
300 GitHub stars now and counting for the "clean" Quarto presentation theme. So you know it's good. github.com/grantmcdermo...
Screenshot of a Quarto reveal.js presentation using the "clean" theme.
1261
Grant McDermott @gmcd.bsky.social · 03/06/2025
4. Better NSE support means less typing for plots with x/ymin and x/ymax values, e.g. coefficient plots. (We plan to expand this smart NSE passing to equivalent arguments like weights and subset in a future release.)
library(broom)
mod = tidy(lm(Temp ~ 0 + factor(Month), data = airquality), conf.int = TRUE)

plt(
    estimate ~ term, ymin = conf.low, ymax = conf.high,
    data = mod,
    type = "pointrange", flip = TRUE
)
121
Grant McDermott @gmcd.bsky.social · 03/06/2025
3. Customizing axis labels is now a lot easier thanks to a couple of convenience functions documented here: grantmcdermott.com/tinyplot/man.... You can specify breaks, use formatting shortcut symbols, or even pass custom formatting functions.
plt(
    Income ~ Population, data.frame(state.x77),
    log = "x", 
    xaxl = "l", xaxb = 10^(2:5),
    yaxl = "$"
)
121
Grant McDermott @gmcd.bsky.social · 03/06/2025
2. Another newly supported type: violin plots. You can do all of the regular grouping/faceting stuff, but here's a straightforward example to illustrate. grantmcdermott.com/tinyplot/man...
plt(count ~ spray, data = InsectSprays, type = "violin")
131