可视化:分组环状条形图

前言

  上一个帖子《可视化:环状条形图》分享了如何绘制基础的环状条形图,今天接着分享复杂一点的环状条形图如何绘制,例如有分组时如何让图形更加美观大气。下面让我们一起拭目以待。

分组环状条形图

  下面就是全部的绘图过程,废话不多说了,先直接来看下面的代码:

library(ggplot2)
library(tidyverse)

set.seed(21)
# 准备数据
data <- data.frame(
  individual=paste( "Mister", seq(1,60), sep=""),
  group=c( rep('A', 10), rep('B', 30), rep('C', 14), rep('D', 6)) ,
  value=sample( seq(10,100), 60, replace=T)
)

# 为了组间的柱子有间隙
empty_bar <- 3
to_add <- data.frame( matrix(NA, empty_bar *nlevels(data$group), ncol(data)) )
colnames(to_add) <- colnames(data)
to_add$group <- rep(levels(data$group), each=empty_bar )
data <- rbind(data, to_add)
data <- data[order(data$group),]
data$id <- seq(1, nrow(data))

# 每个柱子标签的位置
label_data <- data
angle <- 90 - 360 * (label_data$id-0.5) /nrow(label_data)
label_data$hjust <- ifelse( angle < -90, 1, 0)
label_data$angle <- ifelse(angle < -90, angle+180, angle)
 
# 组名和下滑线的位置数据
base_data <- data %>% 
  group_by(group) %>% 
  summarize(start=min(id), end=max(id) - empty_bar) %>% 
  rowwise() %>% 
  mutate(title=mean(c(start, end)))
 
# 填充组间的间隙数据
grid_data <- data %>% 
   filter(is.na(individual)) %>% 
   group_by(group) %>% 
   summarize(start=min(id), end=max(id)) %>% 
   slice_head(n = 3)
 
# 画图
p <- ggplot(data) + 
geom_bar(aes(x=as.factor(id), y=value, fill=group), stat="identity", alpha=0.5) +
            ylim(-100,120) +
            theme_minimal() +
            theme(legend.position = "none",axis.text = element_blank(),axis.title = element_blank(),panel.grid = element_blank()) + 
            geom_text(data=label_data, aes(x=id, y=value+10, label=individual, hjust=hjust), color="black", fontface="bold",alpha=0.6, size=5, angle= label_data$angle)+
            coord_polar()

  # 填充组间间隙
p <-  p + geom_segment(data=grid_data, aes(x = start, y = 80, xend = end, yend = 80), colour = "grey", alpha=1, size=0.3) +
          geom_segment(data=grid_data, aes(x = start, y = 60, xend = end, yend = 60), colour = "grey", alpha=1, size=0.3) +
          geom_segment(data=grid_data, aes(x = start, y = 40, xend = end, yend = 40), colour = "grey", alpha=1, size=0.3) +
          geom_segment(data=grid_data, aes(x = start, y = 20, xend = end, yend = 20), colour = "grey", alpha=1, size=0.3)
  
# 增加Y轴刻度
p <-  p + annotate("text", x = rep(max(data$id),4), y = c(20, 40, 60, 80), label = c("20", "40", "60", "80") , color="grey", size=3 , angle=0, fontface="bold", hjust=1)

# 增加组名和下划线
p <-  p + geom_segment(data=base_data, aes(x = start, y = -5, xend = end, yend = -5), colour = "black", alpha=0.8, size=0.6)  +
          geom_text(data=base_data, aes(x = title, y = -18, label=group), hjust=c(1,1,0,0), colour = "black", alpha=0.8, size=4, fontface="bold")

结果如下:

  分组的环状条形图是不是比常规的条形图看上去颜值要高很多!从上面的绘图过程可以知道,为了到达美观的效果,在每个分组之间增加了一些间隙(灰色的横线),怎么实现的呢?其实很简单,就是在每个分组数据的后面增加一些无效数据,这样绘图的时候就会留下空白,然后再在空白区利用geom_segment函数画上几条横线增加一些高级感。不过,需要注意的是不要把所有的空白区都画上线了,第一个空白区留下来画Y轴的刻度,这样更美观。最后就是利用geom_segmentannotate函数添加分组下划线和组名,这样一幅完整的图就呈现在你的眼前了。

堆叠环状条形图

  这个图又要复杂一些,因为在每个大的分组下,每个柱子又有小的分组,这样的图该怎么画呢?其实画图的中心思想跟上面一致,只不过在数据处理上面稍微复杂一些,上面的图搞明白了,这个图也就水到渠成了。废话不多说了,还是直接看代码吧:

set.seed(21)
# 准备数据
data <- data.frame(
  individual=paste( "Mister", seq(1,60), sep=""),
  group=c( rep('A', 10), rep('B', 30), rep('C', 14), rep('D', 6)) ,
  value1=sample( seq(10,100), 60, replace=T),
  value2=sample( seq(10,100), 60, replace=T),
  value3=sample( seq(10,100), 60, replace=T)
)

data <- data %>% gather(key = "observation", value="value", -c(1,2)) 

# 填充组间的间隙数据
empty_bar <- 2
nobstype <- nlevels(as.factor(data$observation))
to_add <- data.frame( matrix(NA, empty_bar*nlevels(data$group)*nobstype, ncol(data)) )
colnames(to_add) <- colnames(data)
to_add$group <- rep(levels(data$group), each=empty_bar*nobstype)
data <- rbind(data, to_add)
data <- data %>% arrange(group, individual)
data$id <- rep( seq(1, nrow(data)/nobstype) , each=nobstype)

# 每个柱子标签的位置
label_data <- data %>% group_by(id, individual) %>% summarize(tot=sum(value))
angle <- 90 - 360 * (label_data$id-0.5) / nrow(label_data)
label_data$hjust <- ifelse( angle < -90, 1, 0)
label_data$angle <- ifelse(angle < -90, angle+180, angle)

# 组名和下滑线的位置数据
base_data <- data %>% 
  group_by(group) %>% 
  summarize(start=min(id), end=max(id) - empty_bar) %>% 
  rowwise() %>% 
  mutate(title=mean(c(start, end)))
 
# 填充组间的间隙数据
grid_data <- data %>% 
   filter(is.na(individual)) %>% 
   group_by(group) %>% 
   summarize(start=min(id), end=max(id)) %>% 
   slice_head(n = 3)
 
# 画图
p <- ggplot(data) + 
     geom_bar(aes(x=as.factor(id), y=value, fill=observation), stat="identity") +
     scale_fill_brewer(palette = "Set3")+
     ylim(-150,max(data$value)) +
     theme_minimal() +
     theme(legend.position = "none",axis.text = element_blank(),axis.title = element_blank(),panel.grid = element_blank()) + 
     geom_text(data=label_data, aes(x=id, y=tot+10, label=individual, hjust=hjust), color="black", fontface="bold",alpha=0.6, size=2.5, angle= label_data$angle) +
     coord_polar()

  # 填充组间间隙
p <-  p + geom_segment(data=grid_data, aes(x = start, y = 0, xend = end, yend = 0), colour = "grey", alpha=1, size=0.3) + 
          geom_segment(data=grid_data, aes(x = start, y = 50, xend = end, yend = 50), colour = "grey", alpha=1, size=0.3) +
          geom_segment(data=grid_data, aes(x = start, y = 100, xend = end, yend = 100), colour = "grey", alpha=1, size=0.3) +
          geom_segment(data=grid_data, aes(x = start, y = 150, xend = end, yend = 150), colour = "grey", alpha=1, size=0.3) +
          geom_segment(data=grid_data, aes(x = start, y = 200, xend = end, yend = 200), colour = "grey", alpha=1, size=0.3)
  
# 增加Y轴刻度
p <-  p + annotate("text", x = rep(max(data$id),5), y = c(0, 50, 100, 150, 200), label = c("0", "50", "100", "150", "200") , color="grey", size=2.5 , angle=0, fontface="bold", hjust=0.8,vjust=0.1)

# 增加组名和下划线
p <-  p + geom_segment(data=base_data, aes(x = start, y = -5, xend = end, yend = -5), colour = "black", alpha=0.8, size=0.6)  +
          geom_text(data=base_data, aes(x = title, y = -18, label=group), hjust=c(1,1,0,0), colour = "black", alpha=0.8, size=4, fontface="bold")

结果如下:

  堆叠的环状条形图看起来跟分组的相比,绘制过程相同,视觉效果也差不多,仅仅是数据上面复杂度增加一些,呈现出的信息量增加一些。

结束语

  虽然分组的、堆叠的环状条形图稍微复杂一些,但其实理解了其中的小技巧,只需构造出相应的数据,画图还是很顺利的。美好的事情需要经过一些努力才能获得嘛!哦了,今天就分享到这,后面我们继续分享一些其他图形的绘制~~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容