tinyplot icon indicating copy to clipboard operation
tinyplot copied to clipboard

Bee swarm plot

Open devSJR opened this issue 8 months ago • 9 comments

When I was looking at the jitter plot, I was wondering how difficult it might be to implement a bee swarm plot. I know that there is a dedicated package to make these plots but it would be great to have it in tidyplot.

https://github.com/grantmcdermott/tinyplot/blob/6e941b3fe0851ff0bf6e257c5ecea463284140d6/inst%2Ftinytest%2F_tinysnapshot%2Ftinytheme_dynamic_jitter_flip.svg

[Update] I just took a look at the beeswarm package and I noticed that there are actually a lot of options for this plot type.

https://r-charts.com/distribution/beeswarm/

So I think it's not in the scope of tinyplot to re-implement this, as the as a suitable solution.

devSJR avatar Apr 03 '25 19:04 devSJR

I've also just had a quick look at the source code of the beeswarm package and noticed that ggbeeswarm is also relying on that. Even for the basic layouts, they have dedicated C code to set up the point cloud correspondingly.

So I also think that we shouldn't implement this from scratch. Just for fun I tried to ask Gemini for a base R implementation but that wasn't useful at all.

What might be feasible is to use the beeswarm function within a type_beeswarm() driver within tinyplot (similar to what we do for boxplots). Then we would still get by features, faceting, legends, etc. The question is (provided anyone takes this up at all) whether we would consider this within tinyplot with a Suggests dependency on beeswarm - or whether we should try to contribute this to beeswarm.

zeileis avatar Apr 04 '25 06:04 zeileis

Thanks a lot for looking into this. The nice feature about tinyplot is that it's just one package. In this case I have the impression it's better to skip such potential functionality in tinyplot. Otherwise, tinyplot might turn out to be no longer tiny.

devSJR avatar Apr 04 '25 07:04 devSJR

Yes, we definitely don't want to make this a Depends dependency. Personally, I wouldn't have a problem with a Suggests dependency, though, especially because beeswarm doesn't have further dependencies. A cleaner solution, though, would be to implement a tinybeeswarm package that provides the type_beeswarm driver.

zeileis avatar Apr 04 '25 07:04 zeileis

Sure, I understood how you mean it. Maybe it's better to put it on a potential feature list for the future. I also looked at the repository of the package and I saw that alone on GitHub there are 27,000 downloads per month which implies that there is quite a large user base behind this. https://github.com/aroneklund/beeswarm

devSJR avatar Apr 04 '25 08:04 devSJR

I really like these plots too. One thing we could do too (if upstream beeswarm is game) is to have it register and export its C function as callable and tinyplot could access it (just how xts / zoo and Matrix / lme4 and others work).

But the bigger "if" of course is whether tinyplot wants another Suggests for another optional plot method. Or, as @zeileis muses above, whether shimming a new package in the middle is cleaner.

eddelbuettel avatar Apr 04 '25 14:04 eddelbuettel

I think the R functions they export should suffice and C-level access wouldn't be necessary.

zeileis avatar Apr 04 '25 14:04 zeileis

Agreed as the data volumes will likely remain modest.

For kicks, I took the same (microbenchmark-generated) dataset and fed it to the ggbeswarm::geom_beeswarm(). And let's just that say I was underwhelmed. There is a bit of a mismatch between 'N going up' for benchmark results being meaningly, and the beeswarm approach avoiding overplotting.

That said, for smaller data this may well be nice to have.

eddelbuettel avatar Apr 05 '25 15:04 eddelbuettel

Reading through the comments quickly, am I correct in thinking that this is a similar case to #318?

Specifically, we might add the underlying package (beeswarm) to Suggests and have some logic/messaging that requires the user to install it themselves, before using it as the internal calculation engine (beeswarm(..., do.plot = FALSE).

grantmcdermott avatar May 19 '25 17:05 grantmcdermott

Yes, indeed. I would probably do something like this in the data_beeswarm() for type_beeswarm():

if (!requireNamespace("beeswarm", quietly = TRUE)) {
  stop("please install the 'beeswarm' package which is required for this plot type")
}

zeileis avatar May 20 '25 00:05 zeileis