Teun van den Brand's Avatar

Teun van den Brand

@teunbrand

GitHub: https://github.com/teunbrand

953
Followers
94
Following
163
Posts
28.12.2023
Joined
Posts Following

Latest posts by Teun van den Brand @teunbrand

Post image

Example
```
library(ggplot2)

data.frame(cat = LETTERS[1:5], x = rnorm(5), xend = rnorm(5)) |>
ggplot(aes(x, xend = xend, cat)) +
ggarrow::geom_arrow_segment(
arrow_head = NULL,
stroke_colour = "black", colour = "red",
linewidth = 10
) +
coord_radial(theta = "y")
```

06.03.2026 17:06 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

You can use `ggarrow::geom_arrow_segment(arrow_head = NULL)`. It distinguishes `stroke_colour` for the outline and regular `colour` for the interior. This confusing parametrisation was brought to you 'wanna be like `geom_segment`' 😁

06.03.2026 17:05 πŸ‘ 2 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
An Alternative Conflict Resolution Strategy Rs default conflict management system gives the most recently loaded package precedence. This can make it hard to detect conflicts, particularly when they arise because a package update cr...

You're feeling conflicted.r-lib.org about this?

03.03.2026 21:05 πŸ‘ 2 πŸ” 2 πŸ’¬ 1 πŸ“Œ 0
A screenshot of two reply messages on bluesky commenting on the same post. The reply on top is very negative about the data.table package, saying 'it was just the worst'. The bottom reply instead claims that data.table's syntax is the best thing produced in #rstats.

A screenshot of two reply messages on bluesky commenting on the same post. The reply on top is very negative about the data.table package, saying 'it was just the worst'. The bottom reply instead claims that data.table's syntax is the best thing produced in #rstats.

Never change #rstats, never change

27.02.2026 17:22 πŸ‘ 54 πŸ” 4 πŸ’¬ 0 πŸ“Œ 0

I've been charmed recently by ggiraph. It feels well-integrated and mostly works with extensions even if doesn't wrap them in interactivity. ggplotly sort of 'translates' ggplot figures and some of the more niche settings or extensions don't have a natural translation.

27.02.2026 17:17 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

PDF has a horrible habit messing up font stuff. I'm an SVG enthusiast myself and I use ggrastr when my plot has too many points.

25.02.2026 21:38 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

A humble suggestion:

```
`%xtab%` <- function(x, y) {
table(x, y, dnn = list(
deparse(substitute(x)),
deparse(substitute(y))
))
}
```

24.02.2026 17:15 πŸ‘ 5 πŸ” 1 πŸ’¬ 0 πŸ“Œ 0
Post image

How can you say this when theme_barbie() exists? (cc @matthewbjane.bsky.social)

23.02.2026 12:09 πŸ‘ 8 πŸ” 1 πŸ’¬ 1 πŸ“Œ 0
Post image

'ignored positional aesthetics' are so handy and cool, wanted to share on bsky! (as seen on mastodon πŸ™ƒ) #rstats #ggplot2

11.02.2026 20:46 πŸ‘ 15 πŸ” 1 πŸ’¬ 0 πŸ“Œ 0
Preview
ggplot2 styling This post discusses one function in ggplot2: `theme()`. Find out about the glamour of graphics in this deep-dive article.

You can use this instead of your `update_geom_defaults()`:
```
theme(geom = element_geom(linewidth = 0.25, borderwidth = 0.25, pointsize = 0.5))
```
And you can use `set_theme()` to globally apply a theme as the default theme.

I wrote some additional tricks here: tidyverse.org/blog/2025/10...

10.02.2026 10:31 πŸ‘ 3 πŸ” 1 πŸ’¬ 0 πŸ“Œ 0

ONE OF US, ONE OF US, ONE OF US ✨https://github.com/ggplot2-extenders/ggplot-extension-club ✨

05.02.2026 17:21 πŸ‘ 2 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Look the use of the word 'extension' was very deliberate to absolve ggplot2 from having to absorb more functionality than it already does πŸ˜…

05.02.2026 17:07 πŸ‘ 3 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

I like this use case for a facet extension!

05.02.2026 16:41 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

I think this may come from Afrikaans/Dutch and means 'red forest', so bois (woods) wasn't too far of 🀷

05.02.2026 12:18 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Preview
dplyr 1.2.0 dplyr 1.2.0 fills in some important gaps in dplyr's API: we've added a new complement to `filter()` focused on dropping rows, and we've expanded the `case_when()` family with three new recoding and re...

dplyr 1.2.0 is out now and we are SO excited!

- `filter_out()` for dropping rows

- `recode_values()`, `replace_values()`, and `replace_when()` that join `case_when()` as a complete family of recoding/replacing tools

These are huge quality of life wins for #rstats!

tidyverse.org/blog/2026/02...

04.02.2026 11:39 πŸ‘ 466 πŸ” 133 πŸ’¬ 12 πŸ“Œ 14

# pretty slick
l <- c(mpg = "Miles per gallon", wt = "Weight (1,000 lbs)", `mpg/2` = "yes this works")
ggplot(mtcars, aes(mpg, wt)) + labs(dictionary = l)
ggplot(mtcars, aes(wt, mpg)) + labs(dictionary = l)
ggplot(mtcars, aes(wt, mpg/2)) + labs(dictionary = l)

29.01.2026 21:43 πŸ‘ 38 πŸ” 6 πŸ’¬ 2 πŸ“Œ 1

This is a very good primer on why we encounter breaking changes whenever ggplot2 has a meaningful update πŸ™ƒ

21.01.2026 20:31 πŸ‘ 10 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

A second crime is not putting these on the y-axis and displaying the names horizontally.

21.01.2026 19:48 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

It is a (relatively) new thing πŸŽ‰

19.01.2026 22:08 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

You can specify relative position in ggplot with I(x) I(y).

E.g. annotate("text", x = I(.5), y = I(.5), label = "hello!") will place the text in the middle of the plot.
This, combined with alignment arguments is like 87% of the magic for me.

26.12.2025 07:05 πŸ‘ 111 πŸ” 29 πŸ’¬ 3 πŸ“Œ 5

They're alright if you have mutually inclusive categories, mostly as an alternative for large venn-diagram like data. Here, KO/WT are mutually exclusive and 8h/24h/48h are mutually exclusive. I'd opt for other ways of emphasising the experimental conditions.

09.01.2026 21:57 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Where'd be the artistry in deftly replacing `theme_gray()` with something more sensible? You gotta give the people some sense of accomplishment for free.

09.01.2026 21:46 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

lukewarm take, but plotly is uggy and ggplotly should generally be avoided for disrespecting your static ggplot2 formatting (use ggiraph instead)

05.01.2026 19:52 πŸ‘ 9 πŸ” 2 πŸ’¬ 2 πŸ“Œ 0

If there is a fear that some undocumented behaviour you rely on may break on accident, one thing you could do is PR a unit test for the behaviour. At least then, it'll only be broken purposefully πŸ™ƒ

15.12.2025 11:25 πŸ‘ 2 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Side-by-side comparison of two multi-panel bubble charts faceted by world region. The left column shows the default facet labels placed above each panel (β€œAfrica”, β€œAmericas”, β€œAsia”, β€œEurope”, β€œOceania”). The right column shows the same charts, but the facet labels are moved inside each panel at the top-left using a negative margin. In the center, there is a title reading β€œWant to place your facet labels inside each panel?” with an arrow pointing right, followed by a short ggplot2 theme code snippet demonstrating how to move strip text inside the panel.

Side-by-side comparison of two multi-panel bubble charts faceted by world region. The left column shows the default facet labels placed above each panel (β€œAfrica”, β€œAmericas”, β€œAsia”, β€œEurope”, β€œOceania”). The right column shows the same charts, but the facet labels are moved inside each panel at the top-left using a negative margin. In the center, there is a title reading β€œWant to place your facet labels inside each panel?” with an arrow pointing right, followed by a short ggplot2 theme code snippet demonstrating how to move strip text inside the panel.

I ignored the strip.clip argument in #ggplot2 for way too long 😲

Combined with a small negative margin tweak, you can place facet labels inside each panel. A tiny trick that makes small multiples feel so much cleaner.

πŸ”΅ no manual coordinates
πŸ”΅ inherits theme styling
πŸ”΅ scales nicely when resizing

12.12.2025 12:51 πŸ‘ 239 πŸ” 40 πŸ’¬ 7 πŸ“Œ 4
Post image

You can use character glyphs as shapes too. That includes emoji.

```
library(ggplot2)

ggplot(mpg, aes(displ, hwy, shape = fl)) +
geom_point(size = 5) +
scale_shape_manual(values = c("πŸ«›", "πŸ“", "πŸ₯•", "πŸ‹", "πŸ‡"))
```

11.12.2025 12:21 πŸ‘ 4 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Preview
Point Paths β€” geom_pointpath The point path geom is used to make a scatterplot wherein the points are connected with lines in some order. This geom intends to mimic the type = 'b' style of base R line plots.

I made a geom that can do this, but it had a different purpose in mind, so you have to use `mult = 0`. You can use:

```r
stat_summary(
geom = ggh4x::GeomPointpath, fun = mean, color = "red",
mult = 0
)
```

teunbrand.github.io/ggh4x/refere...

09.12.2025 16:22 πŸ‘ 2 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

``` r
func <- function(x) deparse(substitute(x))

mtcars |> func()
#> [1] "mtcars"
mtcars |> dplyr::select(hp, mpg) |> func()
#> [1] "dplyr::select(mtcars, hp, mpg)"
```

28.11.2025 15:48 πŸ‘ 6 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Preview
tidyr: Tidy Messy Data Tools to help to create tidy data, where each column is a variable, each row is an observation, and each cell contains a single value. 'tidyr' contains tools for changing the shape (pivoting) and hier...

Also, packages on CRAN come with a DOI that can be included: doi.org/10.32614/CRA...

25.11.2025 11:45 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Purrrfectly parallel, purrrfectly distributed (Charlie Gao, Posit) | posit::conf(2025)
Purrrfectly parallel, purrrfectly distributed (Charlie Gao, Posit) | posit::conf(2025) YouTube video by Posit PBC

Everyone can now view my posit::conf 2025 talk "purrrfectly parallel, purrrfectly distributed"!

{purrr} now lets you access the magic of {mirai} directly, as the modern way to make things faster through parallel computation in #rstats.

youtu.be/j1yHjMvbnQM?...

17.11.2025 11:30 πŸ‘ 27 πŸ” 3 πŸ’¬ 1 πŸ“Œ 0