I'm trying to make donut charts.
Only problem is they come out looking like this...
Here's my code
ggplot(
diamonds,
aes(
x = cut,
fill = color
)
) +
geom_bar(
position = 'fill',
stat = 'bin'
) +
scale_y_continuous(
labels = percent_format()
) +
facet_grid(clarity ~ cut) +
coord_polar(theta = 'y')
How do I turn my charts from weird pies into circles with the same width?
Here's a nice and tidy way to do it:
library(ggplot2)
library(data.table)
# get data, calculate quantities of interest
diam <- diamonds; setDT(diam)
tabulated <- diam[, .N, by = .(cut, color, clarity)]
# plot
ggplot(tabulated, aes(x=2, y=N, fill=color)) +
geom_bar(position = 'fill', stat = 'identity') +
facet_grid(clarity ~ cut) +
xlim(0.5, 2.5) +
coord_polar(theta = 'y') +
labs(x=NULL, y=NULL)
Ok, how does this work? Let's look at your code - you get some plots that look like donuts but with varying hole sizes. Why is that? It's helpful to 'unpie' the data and just look at the output as bars. (I'm going to subset to just two rows of your facets for simplicity.)
ggplot(subset(diamonds, as.numeric(clarity) <=2),
aes(x = cut, fill = color)) +
geom_bar(position = 'fill', stat = 'bin') +
facet_grid(clarity ~ cut)
You have a value mapped to X that isn't doing anything useful -- it's offsetting the bars, but since you are faceting on that variable each plot only has one stack of bars in it.
Yet when you add coord_polar
, the plots with offset X values show up as donuts, while the plot with x=1 shows up as a pie That's because with coord_polar
, the series of stacked bars are nested inside each other, and X=1 means the innermost 'coil'.
So, the solution begins with NOT mapping a real value to X. You can make X=1 for all plots, but then you'll get all pies, not donuts. What you want is a stacked bar, with some space before it on the x-axis (that’ll be the donut hole). You could do this by duplicating the data, so you have two sets stacked bars, then blanking out the first stack. That’s the answer I had up before, and it works (see edit history for details).
Hadley suggested a simpler solution via twitter, though, which I feel obligated to post for posterity: adjust the x limits to force some leading blank space on the x axis.
To begin, calculate the values you want (I'm using data.table
for this):
library(data.table)
diam <- diamonds; setDT(diam)
tabulated <- diam[, .N, by = .(cut, color, clarity)]
Now plot, with some room before the stack of bars
There's the stacked bar chart you want, and all you have to do is add coord_polar
(as done at the top of the post). You can play with the x limits to tune the donut/hole ratio to your liking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With