制作一个圆形的中心(又名赛道图)

我被要求重新创build以下风格的情节。 (请忽略这是否是一种很好的可视化types的问题,并且可以认为这是为数字表添加一个彩色元素。

其中大部分是相当简单的,但我还没有find一个好的方法,使中心空心。 为了时间的利益,我可以诉诸添加隐形的虚拟数据(我会张贴这种方法,如果没有其他人做,但似乎不如最好的修改主题)。 有没有基于主题的解决scheme或非ggplot2 R解决scheme?

我们在模仿什么

在这里输入图像说明

简单的ggplot2结果(不需要的填充中心)

library(ggplot2) # make sample dataframe Category <- c("Electronics", "Appliances", "Books", "Music", "Clothing", "Cars", "Food/Beverages", "Personal Hygiene", "Personal Health/OTC", "Hair Care") Percent <- c(81, 77, 70, 69, 69, 68, 62, 62, 61, 60) internetImportance<-data.frame(Category,Percent) # append number to category name internetImportance$Category <- paste0(internetImportance$Category," - ",internetImportance$Percent,"%") # set factor so it will plot in descending order internetImportance$Category <- factor(internetImportance$Category, levels=rev(internetImportance$Category)) # plot ggplot(internetImportance, aes(x = Category, y = Percent, fill = Category)) + geom_bar(width = 0.9, stat="identity") + coord_polar(theta = "y") + xlab("") + ylab("") + ylim(c(0,100)) + ggtitle("Top Product Categories Influenced by Internet") + geom_text(data = internetImportance, hjust = 1, size = 3, aes(x = Category, y = 0, label = Category)) + theme_minimal() + theme(legend.position = "none", panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_blank(), axis.text.y = element_blank(), axis.text.x = element_blank(), axis.ticks = element_blank()) 

在这里输入图像说明

我们怎样才能将这些数据绘制成空心的?

下面是使用plotrix软件包的非ggplot2(base R graphics)解决scheme,它包含两个很好的函数: draw.circle()draw.arc()

 circBarPlot <- function(x, labels, colors=rainbow(length(x)), cex.lab=1) { require(plotrix) plot(0,xlim=c(-1.1,1.1),ylim=c(-1.1,1.1),type="n",axes=F, xlab=NA, ylab=NA) radii <- seq(1, 0.3, length.out=length(x)) draw.circle(0,0,radii,border="lightgrey") angles <- (1/4 - x)*2*pi draw.arc(0, 0, radii, angles, pi/2, col=colors, lwd=130/length(x), lend=2, n=100) ymult <- (par("usr")[4]-par("usr")[3])/(par("usr")[2]-par("usr")[1])*par("pin")[1]/par("pin")[2] text(x=-0.02, y=radii*ymult, labels=paste(labels," - ", x*100, "%", sep=""), pos=2, cex=cex.lab) } circBarPlot(Percent/100, Category) text(0,0,"GLOBAL",cex=1.5,col="grey") 

它给了我:

圆形条形图

我认为立即修复是创build一些“空”的条目。 我会创buildinternetImportance data.frame像这样:

 Category <- c("Electronics", "Appliances", "Books", "Music", "Clothing", "Cars", "Food/Beverages", "Personal Hygiene", "Personal Health/OTC", "Hair Care") Percent <- c(81, 77, 70, 69, 69, 68, 62, 62, 61, 60) internetImportance <- data.frame(Category,Percent) len <- 4 df2 <- data.frame(Category = letters[1:len], Percent = rep(0, len), Category2 = rep("", len)) internetImportance$Category2 <- paste0(internetImportance$Category," - ",internetImportance$Percent,"%") # append number to category name internetImportance <- rbind(internetImportance, df2) # set factor so it will plot in descending order internetImportance$Category <- factor(internetImportance$Category, levels=rev(internetImportance$Category)) 

然后我会用fill=category2来绘制ggplot2 ,如下所示:

 ggplot(internetImportance, aes(x = Category, y = Percent, fill = Category2)) + geom_bar(width = 0.9, stat="identity") + coord_polar(theta = "y") + xlab("") + ylab("") + ylim(c(0,100)) + ggtitle("Top Product Categories Influenced by Internet") + geom_text(data = internetImportance, hjust = 1, size = 3, aes(x = Category, y = 0, label = Category2)) + theme_minimal() + theme(legend.position = "none", panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_blank(), axis.text.y = element_blank(), axis.text.x = element_blank(), axis.ticks = element_blank()) 

这给了我:

在这里输入图像说明

您可以在geom_text(label="GLOBAL", x=.5, y=.5, size=4) +添加geom_text(label="GLOBAL", x=.5, y=.5, size=4) +以添加文本GLOBAL

另一个不依赖于plotrix软件包的base解决scheme:

 circular.barplot<-function(values, labels, col, cex){ df<-data.frame(values=sort(values), labels=labels[order(values)]) col<-col[order(values)] plot(NA,xlim=c(-1.3,1.3),ylim=c(-1.3,1.3),axes=F, xlab=NA, ylab=NA, asp=1) t<-sapply(df$values,function(x).5*pi-seq(0, 2*pi*x/100,length=1000)) x<-sapply(1:nrow(df),function(x)(.3+x/nrow(df))*cos(t[,x])) y<-sapply(1:nrow(df),function(x)(.3+x/nrow(df))*sin(t[,x])) for(i in 1:nrow(df)){ lines(x=x[,i],y=y[,i],col=col[i],lwd=10,lend=1) text(x[1,i],y[1,i],paste(df$labels[i]," - ",df$values[i],"%",sep=""), pos=2,cex=cex) } } 

在这里输入图像说明

由于情节是循环的,可以通过circlize易地完成。

首先是数据:

 Category <- c("Electronics", "Appliances", "Books", "Music", "Clothing", "Cars", "Food/Beverages", "Personal Hygiene", "Personal Health/OTC", "Hair Care") Percent <- c(81, 77, 70, 69, 69, 68, 62, 62, 61, 60) color = rainbow(length(Percent)) 

反转三个向量,因为circlize添加了从内部到外部的每个元素:

 Category = rev(Category) Percent = rev(Percent) color = rev(color) 

如果你的图像圆是一个弯曲的情节区域,那么它只是添加矩形,线条和文本。

 library(circlize) par(mar = c(1, 1, 1, 1)) circos.par("start.degree" = 90) circos.initialize("a", xlim = c(0, 100)) # 'a` just means there is one sector circos.trackPlotRegion(ylim = c(0.5, length(Percent)+0.5), track.height = 0.8, bg.border = NA, panel.fun = function(x, y) { xlim = get.cell.meta.data("xlim") # in fact, it is c(0, 100) for(i in seq_along(Percent)) { circos.lines(xlim, c(i, i), col = "#CCCCCC") circos.rect(0, i - 0.45, Percent[i], i + 0.45, col = color[i], border = "white") circos.text(xlim[2], i, paste0(Category[i], " - ", Percent[i], "%"), adj = c(1, 0.5)) } }) circos.clear() text(0, 0, "GLOBAL", col = "#CCCCCC") 

在这里输入图像说明