R语言绘制旭日图(嵌套多层的饼图或圆环图)
对,KRONA软件(https://github.com/marbl/Krona/wiki)的默认作图结构就是这种类型的,下面这个图对于很多同学们来说都不陌生吧,它的交互式界面也更便于查看。
接下来就展示这种图怎样绘制。
KRONA软件本篇就不涉及它了,主要是R语言的绘制方法,并且R语言也可以绘制这种交互式界面哦。
Excel绘制旭日图
先展示一下Excel作图,上述一开始时展示的那个示例图,是直接拿Excel获得的。
如上所示,选中给定数据的列,在Excel上方点击插入图表,选择旭日图。
出来图片后,再调整字体大小、背景色、主题样式等就就可以了。
热身之后,接下来是R语言作图,可比Excel丰富得多。
以下展示一些示例吧,网上扒下来的,足以满足日常作图的需求。
pie()作图
最基本的,饼图函数pie()绘制不同大小的饼图叠加起来。
#一个简单的旭日图,2 层的圆环状结构,参考自
#https://stackoverflow.com/questions/26748069/ggplot2-pie-and-donut-chart-on-same-plot
#模拟数据
browsers<-structure(list(
browser = structure(c(3L, 3L, 3L, 3L, 2L, 2L, 2L, 1L, 5L, 5L, 4L), .Label = c('Chrome', 'Firefox', 'MSIE', 'Opera', 'Safari'),),
version = structure(c(5L, 6L, 7L, 8L, 2L, 3L, 4L, 1L, 10L, 11L, 9L), .Label = c('Chrome 10.0', 'Firefox 3.5', 'Firefox 3.6', 'Firefox 4.0', 'MSIE 6.0', 'MSIE 7.0', 'MSIE 8.0', 'MSIE 9.0', 'Opera 11.x', 'Safari 4.0', 'Safari 5.0'),),
share = c(10.85, 7.35, 33.06, 2.81, 1.58, 13.12, 5.43, 9.91, 1.42, 4.55, 1.65),
ymax = c(10.85, 18.2, 51.26, 54.07, 55.65, 68.77, 74.2, 84.11, 85.53, 90.08, 91.73),
ymin = c(0, 10.85, 18.2, 51.26, 54.07, 55.65, 68.77, 74.2, 84.11, 85.53, 90.08)),
.Names = c('browser', 'version', 'share', 'ymax', 'ymin'), row.names = c(NA, -11L), class = 'data.frame')
#使用常规的 pie() 作图
tbl <- table(browsers$browser)[order(unique(browsers$browser))]
col.main <- Map(rep, seq_along(tbl), tbl)
col.sub <- lapply(col.main, function(x) Vectorize(adjustcolor)(x, alpha.f = seq_along(x) / length(x)))
pie(browsers$share, border = NA, radius = 1, col = unlist(col.sub), labels = browsers$version)
par(new = TRUE)
pie(browsers$share, border = NA, radius = 0.8, col = unlist(col.main), labels = NA)
ggplot2包作图
ggplot2怎么能少得了呢,通过绘制多组柱形图,然后变换坐标系即可获得多层的饼图或圆环图。
#接续使用上述数据
#ggplot2 作图,通过柱形图经极坐标变换得到
library(ggplot2)
p <- 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)
p
p + coord_polar(theta = 'y')
#类似本篇开始时的 Excel 示例,标签显示在圆环内部,参考自
#https://stackoverflow.com/questions/50004058/multiple-dependent-level-sunburst-doughnut-chart-using-ggplot2
library(ggplot2)
df <- data.frame(name = c('foo', 'foo', 'foo', 'bar', 'bar', 'baz', 'baz', 'baz'),
type = c('all', 'type1', 'type2', 'all', 'type3', 'all', 'type1', 'type3'),
value = c(444, 123, 321, 111, 111, 999, 345, 653),
level = c('1', '2', '2', '1', '2', '1', '2', '2'))
ggplot(df, aes(x = level, y = value, fill = name, alpha = level)) +
geom_col(width = 1, color = 'gray90', size = 0.25, position = position_stack()) +
geom_text(aes(label = name), size = 2.5, position = position_stack(vjust = 0.5)) +
coord_polar(theta = 'y') +
scale_alpha_manual(values = c('0' = 0, '1' = 1, '2' = 0.7), guide = F) +
scale_x_discrete(breaks = NULL) +
scale_y_continuous(breaks = NULL) +
scale_fill_brewer(palette = 'Dark2', na.translate = F) +
labs(x = NULL, y = NULL) +
theme_minimal()
ggsunburst包作图
ggsunburst的旭日图也是很好看的,这是个专用于绘制旭日图的包,尽管这个包安装起来有点麻烦……
#ggsunburst 包的旭日图,参考自
#https://stackoverflow.com/questions/26748069/ggplot2-pie-and-donut-chart-on-same-plot/37015211
#rPython 仅在 Linux 或 Mac 下可用 install.packages() 安装
#Windows 下可通过该方法安装:https://github.com/cjgb/rPython-win
if (!require('ggplot2')) install.packages('ggplot2')
if (!require('rPython')) install.packages('rPython')
install.packages('http://genome.crg.es/~didac/ggsunburst/ggsunburst_0.0.9.tar.gz', repos = NULL, type = 'source')
library(ggsunburst)
#模拟数据
browsers<-structure(list(
browser = structure(c(3L, 3L, 3L, 3L, 2L, 2L, 2L, 1L, 5L, 5L, 4L), .Label = c('Chrome', 'Firefox', 'MSIE', 'Opera', 'Safari'),),
version = structure(c(5L, 6L, 7L, 8L, 2L, 3L, 4L, 1L, 10L, 11L, 9L), .Label = c('Chrome 10.0', 'Firefox 3.5', 'Firefox 3.6', 'Firefox 4.0', 'MSIE 6.0', 'MSIE 7.0', 'MSIE 8.0', 'MSIE 9.0', 'Opera 11.x', 'Safari 4.0', 'Safari 5.0'),),
share = c(10.85, 7.35, 33.06, 2.81, 1.58, 13.12, 5.43, 9.91, 1.42, 4.55, 1.65),
ymax = c(10.85, 18.2, 51.26, 54.07, 55.65, 68.77, 74.2, 84.11, 85.53, 90.08, 91.73),
ymin = c(0, 10.85, 18.2, 51.26, 54.07, 55.65, 68.77, 74.2, 84.11, 85.53, 90.08)),
.Names = c('browser', 'version', 'share', 'ymax', 'ymin'), row.names = c(NA, -11L), class = 'data.frame')
browsers$browser <- browsers$parent
write.table(browsers, file = 'browsers.csv', row.names = FALSE, sep = ',')
sb <- sunburst_data('browsers.csv', type = 'node_parent', sep = ',', node_attributes = c('browser', 'size'))
#为内部节点添加名称以着色
sb$rects[!sb$rects$leaf,]$browser <- sb$rects[!sb$rects$leaf,]$name
#作图
p <- sunburst(sb, rects.fill.aes = 'browser', node_labels = TRUE, node_labels.min = 15)
p + geom_text(data = sb$leaf_labels,
aes(x = x, y = 0.1, label=paste(size, '%'), angle = angle, hjust = hjust), size = 2)
sunburstR包作图
sunburstR包交互式的旭日图,样式也是非常的美观。
#sunburstR 包的交互式旭日图,参考自
#https://stackoverflow.com/questions/12926779/how-to-make-a-sunburst-plot-in-r-or-python
library(sunburstR)
sequences <- read.csv(system.file('examples/visit-sequences.csv', package = 'sunburstR'), header = FALSE, stringsAsFactors = FALSE)
sunburst(sequences)
plotly包作图
既然是交互式图形,怎么能少得了plotly包呢,再来俩示例。
#plotly 包的交互式旭日图,参考自
#https://plot.ly/r/sunburst-charts/
library(plotly)
p <- plot_ly(
labels = c('Eve', 'Cain', 'Seth', 'Enos', 'Noam', 'Abel', 'Awan', 'Enoch', 'Azura'),
parents = c('', 'Eve', 'Eve', 'Seth', 'Seth', 'Eve', 'Eve', 'Awan', 'Eve'),
values = c(10, 14, 12, 10, 2, 6, 6, 4, 4),
type = 'sunburst'
)
p
#继续展示 plotly 包交互式图形
library(plotly)
d <- data.frame(
ids = c(
'North America', 'Europe', 'Australia', 'North America - Football', 'Soccer',
'North America - Rugby', 'Europe - Football', 'Rugby',
'Europe - American Football','Australia - Football', 'Association',
'Australian Rules', 'Autstralia - American Football', 'Australia - Rugby',
'Rugby League', 'Rugby Union'
),
labels = c(
'North<br>America', 'Europe', 'Australia', 'Football', 'Soccer', 'Rugby',
'Football', 'Rugby', 'American<br>Football', 'Football', 'Association',
'Australian<br>Rules', 'American<br>Football', 'Rugby', 'Rugby<br>League',
'Rugby<br>Union'
),
parents = c(
'', '', '', 'North America', 'North America', 'North America', 'Europe',
'Europe', 'Europe','Australia', 'Australia - Football', 'Australia - Football',
'Australia - Football', 'Australia - Football', 'Australia - Rugby',
'Australia - Rugby'
),
stringsAsFactors = FALSE
)
p <- plot_ly(d, ids = ~ids, labels = ~labels, parents = ~parents, type = 'sunburst')
p