Instantly share code, notes, and snippets.

Embed
What would you like to do?
# somewhat hackish solution to:
# https://twitter.com/EamonCaddigan/status/646759751242620928
# based mostly on copy/pasting from ggplot2 geom_violin source:
# https://github.com/hadley/ggplot2/blob/master/R/geom-violin.r
library(ggplot2)
library(dplyr)
"%||%" <- function(a, b) {
if (!is.null(a)) a else b
}
geom_flat_violin <- function(mapping = NULL, data = NULL, stat = "ydensity",
position = "dodge", trim = TRUE, scale = "area",
show.legend = NA, inherit.aes = TRUE, ...) {
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomFlatViolin,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
trim = trim,
scale = scale,
...
)
)
}
#' @rdname ggplot2-ggproto
#' @format NULL
#' @usage NULL
#' @export
GeomFlatViolin <-
ggproto("GeomFlatViolin", Geom,
setup_data = function(data, params) {
data$width <- data$width %||%
params$width %||% (resolution(data$x, FALSE) * 0.9)
# ymin, ymax, xmin, and xmax define the bounding rectangle for each group
data %>%
group_by(group) %>%
mutate(ymin = min(y),
ymax = max(y),
xmin = x,
xmax = x + width / 2)
)
},
draw_group = function(data, panel_scales, coord) {
# Find the points for the line to go all the way around
data <- transform(data, xminv = x,
xmaxv = x + violinwidth * (xmax - x))
# Make sure it's sorted properly to draw the outline
newdata <- rbind(plyr::arrange(transform(data, x = xminv), y),
plyr::arrange(transform(data, x = xmaxv), -y))
# Close the polygon: set first and last point the same
# Needed for coord_polar and such
newdata <- rbind(newdata, newdata[1,])
ggplot2:::ggname("geom_flat_violin", GeomPolygon$draw_panel(newdata, panel_scales, coord))
},
draw_key = draw_key_polygon,
default_aes = aes(weight = 1, colour = "grey20", fill = "white", size = 0.5,
alpha = NA, linetype = "solid"),
required_aes = c("x", "y")
)
### Example:
ggplot(diamonds, aes(cut, carat)) +
geom_flat_violin() +
coord_flip()
@benmarwick

This comment has been minimized.

benmarwick commented Mar 27, 2016

I think you might have a stray closing parenthesis on L50 (I needed to remove it to make it work with ggplot2_2.1.0).

@peterparkerspicklepatch

This comment has been minimized.

peterparkerspicklepatch commented May 3, 2016

Can someone repost this? It's become a hunt for parenthesis.

@mvuorre

This comment has been minimized.

mvuorre commented Jan 4, 2017

Hi, are there any plans to include this in future versions of ggplot2? The geom is great and would be great to have it more easily accessible.

Thanks for sharing

@sahirmoosvi

This comment has been minimized.

sahirmoosvi commented Jan 18, 2017

In case someone needs to find that comma... The mutate command has two end braces when it should just have one.

mutate(ymin = min(y),
    ymax = max(y), 
    xmin = x,
    xmax = x + width / 2)
)                      # <---- Take this one out
@Maja-Ilic-AquaEco

This comment has been minimized.

Maja-Ilic-AquaEco commented Dec 8, 2018

This is so great! I will most definitely use this for a figure within a manuscript which I am preparing for publication. Please let me know if there is any need to cite the code and how. And thanks for this great contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment