ggplot2 pie and donut chart on same plot

匿名 (未验证) 提交于 2019-12-03 02:52:02

问题:

I am trying to replicate this

with R ggplot. I have exactly the same data:
browsers

and it looks like this:

> browsers    browser      version  share   ymax   ymin 1     MSIE     MSIE 6.0  10.85  10.85   0.00 2     MSIE     MSIE 7.0   7.35  18.20  10.85 3     MSIE     MSIE 8.0  33.06  51.26  18.20 4     MSIE     MSIE 9.0   2.81  54.07  51.26 5  Firefox  Firefox 3.5   1.58  55.65  54.07 6  Firefox  Firefox 3.6  13.12  68.77  55.65 7  Firefox  Firefox 4.0   5.43  74.20  68.77 8   Chrome  Chrome 10.0   9.91  84.11  74.20 9   Safari   Safari 4.0   1.42  85.53  84.11 10  Safari   Safari 5.0   4.55  90.08  85.53 11   Opera   Opera 11.x   1.65  91.73  90.08 

So far, I have plotted the individual components (i.e. the donut chart of the versions, and the pie chart of the browsers) like so:

ggplot(browsers) + geom_rect(aes(fill=version, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) + coord_polar(theta="y") + xlim(c(0, 4)) 

ggplot(browsers) + geom_bar(aes(x = factor(1), fill = browser),width = 1) + coord_polar(theta="y") 

The problem is, how do I combine the two to look like the topmost image? I have tried many ways, such as:

ggplot(browsers) + geom_rect(aes(fill=version, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) +         geom_bar(aes(x = factor(1), fill = browser),width = 1) + coord_polar(theta="y") + xlim(c(0, 4))  

But all my results are either twisted or end with an error message.

回答1:

I find it easier to work in rectangular coordinates first, and when that is correct, then switch to polar coordinates. The x coordinate becomes radius in polar. So, in rectangular coordinates, the inside plot goes from zero to a number, like 3, and the outer band goes from 3 to 4.

For example

ggplot(browsers) +    geom_rect(aes(fill=version, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) +   geom_rect(aes(fill=browser, ymax=ymax, ymin=ymin, xmax=3, xmin=0)) +   xlim(c(0, 4)) +    theme(aspect.ratio=1)  

Then, when you switch to polar, you get something like what you are looking for.

ggplot(browsers) +    geom_rect(aes(fill=version, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) +   geom_rect(aes(fill=browser, ymax=ymax, ymin=ymin, xmax=3, xmin=0)) +   xlim(c(0, 4)) +    theme(aspect.ratio=1) +   coord_polar(theta="y")   

This is a start, but may need to fine tune the dependency on y (or angle) and also work out the labeling / legend / coloring... By using rect for both the inner and outer rings, that should simplify adjusting the coloring. Also, it can be useful to use the reshape2::melt function to reorganize the data so then legend comes out correct by using group (or color).



回答2:

Edit 2

My original answer is really dumb. Here is a much shorter version which does most of the work with a much simpler interface.

#' x      numeric vector for each slice #' group  vector identifying the group for each slice #' labels vector of labels for individual slices #' col    colors for each group #' radius radius for inner and outer pie (usually in [0,1])  donuts 


Original post

You guys don't have givemedonutsorgivemedeath function? Base graphics are always the way to go for very detailed things like this. Couldn't think of an elegant way to plot the center pie labels, though.

givemedonutsorgivemedeath('~/desktop/donuts.pdf')  

Gives me

Note that in ?pie you see

Pie charts are a very bad way of displaying information. 

code:

browsers 

Edit 1

width 


回答3:

I created a general purpose donuts plot function to do this, which could

  • Draw ring plot, i.e. draw pie chart for panel and colorize each circular sector by given percentage pctr and colors cols. The ring width could be tuned by outradius>radius>innerradius.
  • Overlay several ring plot together.

The main function actually draw a bar chart and bend it into a ring, hence it is something between a pie chart and a bar chart.

Example Pie Chart, two rings:

Browser Pie Chart

donuts_plot =1) legend.label=paste("Series",1:length(pctr))     if(pilabels){         pie(panel, col=cols,border = borderlit[1],labels = legend.label,radius = outradius)     }     panel = panel/sum(panel)      pctr2= panel*(1 - pctr)     pctr3 = c(pctr,pctr)     pctr_indx=2*(1:length(pctr))     pctr3[pctr_indx]=pctr2     pctr3[-pctr_indx]=panel*pctr     cols_fill = c(cols,cols)     cols_fill[pctr_indx]='white'     cols_fill[-pctr_indx]=cols     par(new=TRUE)     pie(pctr3, col=cols_fill,border = borderlit[2],labels = '',radius = outradius)     par(new=TRUE)     pie(panel, col='white',border = borderlit[3],labels = '',radius = radius)     par(new=TRUE)     pie(1, col='white',border = borderlit[4],labels = '',radius = innerradius)     if(legend){         # par(mar=c(5.2, 4.1, 4.1, 8.2), xpd=TRUE)         legend("topright",inset=c(-legend_offset,0),legend=legend.label, pch=rep(15,'.',length(pctr)),                 col=cols,bty='n')     }     par(new=FALSE) } ## col- > subcor(change hue/alpha) subcolors 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!