I am trying to replicate this
with R ggplot. I have exactly the same data:
<
@rawr's solution is really nice, however, the labels will be overlapped if there are too many. Inspired by @user3969377 and @FlorianGD, I got a new solution using ggplot2 and ggrepel.
browsers$ymax <- cumsum(browsers$share) # fed to geom_rect() in piedonut()
browsers$ymin <- browsers$ymax - browsers$share # fed to geom_rect() in piedonut()
browsers$share_browser <- sum(browsers$share[browsers$browser == unique(browsers$browser)[1]]) # "_browser" means at browser level
browsers$ymax_browser <- browsers$share_browser[browsers$browser == unique(browsers$browser)[1]][1]
for (z in 2:length(unique(browsers$browser))) {
browsers$share_browser[browsers$browser == unique(browsers$browser)[z]] <- sum(browsers$share[browsers$browser == unique(browsers$browser)[z]])
browsers$ymax_browser[browsers$browser == unique(browsers$browser)[z]] <- browsers$ymax_browser[browsers$browser == unique(browsers$browser)[z-1]][1] + browsers$share_browser[browsers$browser == unique(browsers$browser)[z]][1]
}
browsers$ymin_browser <- browsers$ymax_browser - browsers$share_browser
piedonut <- function(data, cols = c('cyan2','red','orange','green','dodgerblue2'), force = 80, nudge_x = 3, nudge_y = 10) { # force, nudge_x, nudge_y are parameters to fine tune positions of the labels by geom_label_repel.
nr <- nrow(data)
# width <- max(sqrt(data$share)) / 0.1
tbl <- with(data, table(browser)[order(unique(browser))])
cols <- unlist(Map(rep, cols, tbl))
col_subnum <- unlist(Map(rep, 255/tbl,tbl))
col <- rep(NA, nr)
col_browser <- rep(NA, nr)
for (i in 1:nr) {
## create color/shades
rgb <- col2rgb(cols[i])
col[i] <- rgb(rgb[1], rgb[2], rgb[3], col_subnum[i]*sequence(tbl)[i], maxColorValue = 255)
rgb <- col2rgb(cols[i])
col_browser[i] <- rgb(rgb[1], rgb[2], rgb[3], maxColorValue = 255)
}
#col
# set labels positions
x.breaks <- seq(1, 1.8, length.out = nr)
y.breaks <- cumsum(data$share)-data$share/2
ggplot(data) +
geom_rect(aes(ymax = ymax, ymin = ymin, xmax=4, xmin=1), fill=col) +
geom_rect(aes(ymax=ymax_browser, ymin=ymin_browser, xmax=1, xmin=0), fill=col_browser) +
coord_polar(theta = 'y') +
theme(axis.ticks = element_blank(),
axis.title = element_blank(),
axis.text = element_blank(),
panel.grid = element_blank(),
panel.background = element_blank()) +
geom_label_repel(aes(x = x.breaks, y = y.breaks, label = sprintf("%s: %s%%",data$version, data$share)),
force = force,
nudge_x = nudge_x,
nudge_y = nudge_y)
}
cols <- c('cyan2','red','orange','green','dodgerblue2')
pdf('~/Downloads/donuts.pdf', width = 10, height = 10, bg = "snow")
par(omi = c(0.5,0.5,0.75,0.5), mai = c(0.1,0.1,0.1,0.1), las = 1)
print(piedonut(data = browsers, cols = cols, force = 80, nudge_x = 3, nudge_y = 10))
dev.off()