class: title-slide-custom, center # Introduction to **ggrepel** .large[ <img src="index_files/logo.svg" width="181px"></img> [github.com/slowkow/ggrepel](https://github.com/slowkow/ggrepel) July 2018 Kamil Slowikowski <br> [@slowkow](https://twitter.com/slowkow) ] ??? - Hello! I'm Kamil Slowikowski, the creator of ggrepel. - I'm also a PhD student in Bioinformatics at Harvard. - I want to show you a brief introduction to ggrepel, so you can get started using it in your figures. --- # 😞 **Problem:** text placement .pull-left[ <br> ```r library(ggplot2) ggplot(mtcars) + aes( x = wt, y = mpg, label = rownames(mtcars) ) + geom_point(color = "red") + * geom_text() ``` ] .pull-right[ ![](index_files/figure-html/problem-1.png)<!-- --> ] ??? - Oftentimes, we want to know the identity of each data point in a figure. - Unfortunately, `geom_text()` does not always work as expected: - text labels often overlap with each other - sometimes they fall outside the plotting area --- # 🎉 **Solution:** ggrepel .pull-left[ <br> ```r library(ggrepel) ggplot(mtcars) + aes( x = wt, y = mpg, label = rownames(mtcars) ) + geom_point(color = "red") + * geom_text_repel() ``` ] .pull-right[ ![](index_files/figure-html/solution-1.png)<!-- --> ] ??? - This problem motivated me to create ggrepel: - an extension for ggplot2 that automatically places text labels without overlaps - I tried to make it very easy to use: - just replace `geom_text()` with `geom_text_repel()` --- # 😊 Much better! ![](index_files/figure-html/ex1-1.png)<!-- --> ??? - Side by side, you can see that the figure using ggrepel is much easier to read because the text is clearly visible. --- # **Repel** text labels away from .pull-left-large[ <br> - other text labels - data points - edges of the plotting area ] .pull-right[ ![](index_files/figure-html/ex2-1.png)<!-- --> ] ??? - The idea behind ggrepel is very simple. - We want to repel text labels away from: - other text labels - data points - and edges of the plotting area --- # 📜 Algorithm .large[ `\(O(n^2)\)` N-body physical simulation ] ![](index_files/figure-html/algorithm-1.png)<!-- --> ??? - I implemented a brute force algorithm of a physical simulation. - We iterate over all pairs of text labels and repel them away from each other. - We use a spring force to pull each text label back to its own data point. - Let's see it in action! --- # 🐎 **ggrepel** in action <video src="index_files/animation.mp4" type="video/mp4" style="height:75%; margin-left:8%;" muted autoplay loop></video> ??? - This is an animation showing each step of the simulation on a loop. - The labels repel away from each other, and away from data points. - There is a spring force that pulls each label back to its own data point. - Notice that "Honda Civic" first moves away from its data point, and then it is pulled back until it is directly adjacent. --- # 🐎 **ggrepel** in action <video src="index_files/resizing.mp4" type="video/mp4" style="height:70%; margin-left:8%;" muted autoplay loop></video> ??? - ggrepel works well with RStudio. - When you resize the plotting area, it will automatically recompute the overlaps and adjust the label positions. --- # 💾 Installation .pull-left-large[ Install **ggrepel** from [CRAN](https://CRAN.R-project.org/package=ggrepel): ```r install.packages("ggrepel") ``` ] .pull-right[ ![](index_files/figure-html/downloads-1.png)<!-- --> ] ??? - ggrepel is easy to install and only depends on ggplot2. It has no other dependencies. - This has quickly become the most popular piece of code I have ever written. - I've learned that people are happy when something just works. - Now let's take a look at a practical example. --- # 🌋 Example: Volcano .large[Which genes show significant differential expression?] ![](index_files/figure-html/volcano-1.png)<!-- --> Thanks to [Stephen Turner] for the example data. [Stephen Turner]: http://www.gettinggeneticsdone.com/2016/01/repel-overlapping-text-labels-in-ggplot2.html ??? - In bioinformatics, we often do a differential gene expression test. - Then, we ask: which genes show significant differential expression? - With ggrepel, we can actually read the gene names. That's great. - However, these figures are not always easy to read. - Sometimes ggrepel is not the best choice... --- # 🤔 Consider other options .pull-left-large[ - **ggrepel** is not always the best choice - Sometimes other plots are easier to read ] .pull-right[ ![](index_files/figure-html/lollipop-1.png)<!-- --> ] ??? - It is not always a good idea to add text labels to your figure. - Sometimes other plots are easier to read. - If possible, try to keep your figures easy to understand. - Because if you're not careful, you might get a surprising result... --- # 🤭 Don't label too many points! .large[ Or else you will end up with [@accidental__aRt] ] <div class="center"> <img src="index_files/accidental-art-1.png" alt="" style="width: 66%;"> </div> [@accidental__aRt]: https://twitter.com/accidental__aRt ??? - I see a lot of figures in the wild with too many text labels! - To avoid this situation, you might consider labeling a small subset of your data points. --- # 💡 Use the empty string "" .pull-left[ ```r library(ggrepel) d <- subset( mtcars, wt > 3 & wt < 4 ) # Just label 3 items. *d$car <- "" *i <- c(2, 3, 16) *d$car[i] <- rownames(d)[i] ggplot(d) + aes(wt, mpg, label = car) + geom_point( color = ifelse( d$car != "", "red", "grey50" ) ) + geom_text_repel() ``` ] .pull-right[ ![](index_files/figure-html/empty-1.png)<!-- --> ] ??? - You can use the empty string to hide most of the labels. - Then you can add labels for just a few data points. - By using the empty string strategy, we are saying that we want the unlabeled data points to continue repelling the text from the labeled data points. --- # 🎓 Learn from examples in the [vignette] ```r vignette("ggrepel") # <- Run this command in RStudio ``` <div class="center"> <img src="index_files/other-examples.png" style="width: 87%;"> </div> [vignette]: https://cran.r-project.org/web/packages/ggrepel/vignettes/ggrepel.html ??? - For more examples, check out the vignette and feel free to copy code. - If you have a new example you'd like to share, please send it along! --- # 🐛 Please report bugs ### [github.com/slowkow/ggrepel/issues](https://github.com/slowkow/ggrepel/issues) <br> .large[ 🎁 Contributions are very welcome! 🙌 We have 8 contributors so far. ❓ [Stackoverflow] is the best place to ask questions. ] [Stackoverflow]: https://stackoverflow.com/search?q=ggrepel ??? - We have many open issues, and I don't have time to fix all of them. - If you want to contribute, please let me know and I'll do my best to get you started. - For questions about using R and making figures, I like to use Stackoverflow - If you want to see more examples of ggplot extensions... --- # 📦 [ggplot2 extension gallery](http://www.ggplot2-exts.org/gallery/) <div class="center"> <img src="index_files/ggplot2-extension-gallery.png" alt="" style="width: 72%;"> </div> ??? - The ggplot2 extension gallery has lots of examples that might meet your needs. - After browsing, you might also get an idea for creating a new extension that is useful for your own work! - If you want to make your own extension... I have some links for you. --- # 🛠️ Make a **ggplot2** extension! .large[⭐ [Extending ggplot2][ext1]] by [Hadley Wickham] .large[⭐ [How to make a generic stat in ggplot2][ext3]] by [Elio Campitelli] .large[🌟 [ggplot2 Internals][ext4] (WOW!)] by [Brodie Gaslam] [ext1]: https://cran.r-project.org/web/packages/ggplot2/vignettes/extending-ggplot2.html [ext3]: https://eliocamp.github.io/codigo-r/2018/05/how-to-make-a-generic-stat-in-ggplot2/ [ext4]: https://htmlpreview.github.io/?https://github.com/brodieG/ggbg/blob/development/inst/doc/extensions.html [Hadley Wickham]: http://hadley.nz/ [Elio Campitelli]: https://github.com/eliocamp [Brodie Gaslam]: http://www.brodieg.com/ ??? - I wish I had these resources when I started developing ggrepel. - Hadley's guide will show you how to make an extension, step by step. - Elio's guide will show you how to make a very generic extension that works with any function which accepts a dataframe as input and produces a similar dataframe as output. - Finally, if you want to learn more about the internals of ggplot, be sure to look at Brodie's guide. It is the most comprehensive and detailed resource about how ggplot2 works. --- # 📚 Related work .large[ ### Python - [adjustText](https://github.com/Phlya/adjustText) ### Javascript - [d3fc-label-layout](https://github.com/d3fc/d3fc-label-layout) ] ??? - If you work with Python or Javascript, you might be interested to check out these projects. - They offer similar functionality to ggrepel. --- class: center .large[ <br><br><br> These slides are available at: <br> ### [slowkow.com/ggrepel](https://slowkow.com/ggrepel) <br> <img src="index_files/twitter.svg" width="32px"></img> Kamil Slowikowski <br> [@slowkow](https://twitter.com/slowkow) ] <br><br> <br><br> Made with ⚔ [xaringan] [xaringan]: https://github.com/yihui/xaringan ??? - These slides are available online, so you can follow the links to all the resources I highlighted. - Feel free to follow me and ask questions on twitter!