专栏名称: EasyCharts
EasyCharts,易图表,我们将定期推送各种数据可视化与分析教程,包括Excel(Power BI)、Origin、Sigmaplot、GraphPad、R、Python、Matlab、Tableau、D3.js等。
目录
相关文章推荐
前端大全  ·  前端行情变了,差别真的挺大。。。 ·  昨天  
前端大全  ·  React+AI 技术栈(2025 版) ·  3 天前  
商务河北  ·  经开区“美•强•优”三重奏 ·  2 天前  
51好读  ›  专栏  ›  EasyCharts

三维柱状图(3D barplot)怎么画

EasyCharts  · 公众号  · 前端  · 2019-12-28 12:07

正文


有人后台留言问我3Dbaplot 怎么画,刚好昨天有个群友也遇到这个问题。于是我在网上搜罗了一下。

哈神(Hadley Wickham)的ggplot2不支持画三维图形(3D plot)。有人在ggplot2的基础上进行开发,造出了一个 gg3D 包,可勉强实现三维坐标系的展示,但可操作性挺差,并没有流行起来。除了基于ggplot2的开发, rgl plot3D scatterplot3d plotly (被称为有史以来最好的可视化工具,R和Python都有相应的扩展包)等这一系列包都支持3D画图。对于多数包,画三维点图(scatter plot)和密度图(density/surface plot)都比较容易实现,然而三维的柱状图(3D barchart)却不太容易实现。

偶然发现一个基于rgl包开发的包 barplot3d 大大方便了三维柱状图的画法。细查之后发现,该包的产生似乎有一段故事:

先附上作者名号: Christopher Wardell

他其实先吐了一下饼图的槽,借用一个文章里的图:

Subclonal diversification of primary breast cancer revealed by multiregion sequencing by Yates et al, 2015

作者说这是150年前流行的图(不知他是说的是不是包括那个以 现代护理学之母 “提灯女神”南丁格尔的名字命名的 南丁格尔玫瑰图 )。

(内心OS:明明很酷的图好吧……)

作者也承认这种图很酷也漂亮,但它们是不合适的并且具有误导性的:

1.这些图看起来不合常理。读者花费了大量的精力来搞清楚他们在看什么,而不是处理数据中的关系。

2.这些数据只包含一个变量,但是上述图表可以表现两个变量(弧长和半径都可以变化)。因此,图表形式过于复杂。

3.在饼状图中,弧长与所表示的值成比例。在这些图中,每一块饼的弧长是相同的,但你可能意识不到,反而你可能会推断出某一段的弧长更少。这适用于弗洛伦斯•南丁格尔(Florence Nightingale)所绘制的数据类型(每年每个月的死亡人数),但不适用于任意划分。(哦,看来 南丁格尔玫瑰图 合理 的。)

4.在这些图中,每一段的半径(即它从中心延伸的距离)都能提供信息。你本应该读出一个几乎看不见的灰色虚线表示的同心圆刻度,但这并不容易。此外,该图视觉效果是非线性的,因为圆的面积是π·r ^ 2,这意味着半径上一个小的增加会产生一个不成比例的大变化。

5.很难在图之间进行比较。视觉比较非常困难,而通过阅读“Scale legend”来获得数字就更困难了。

为了原封不动保留作者的糟点,我基本是直译过来的。

只批评而不提供解决方案是没用的!!!

于是,作者有以下方案可供选择:

a, 柱状图(刚吐过柱状图的槽)。b, 箱线图。c, 3D柱状图

a,b 很boring但很实用,c实现起来略不容易。

这种类型的3D柱状图,首先是在Broad Institute的一篇关于测序文章中出现,继而流行开来。而且还有个不太学术的名字:乐高图(Lego plot)。

Exome and whole-genome sequencing of esophageal adenocarcinoma identifies recurrent driver events and mutational complexity by Dulak et al, 2013

对乐高图一番吹捧之后,能干的作者整出一个R包出来: barplot3d

该包主要包含两个函数: barplot3d() legoplot3d()

下面我们来造数据试以下。

造数据:

1set.seed(1234)
2data 1:5010),
3                   b = sample(1:5010),
4                   c = sample(1:5010),
5                   d = sample(1:5010))
6rownames(data) 1:10]

加载所需的包:

1library(rgl)
2library(barplot3d)
3library(RColorBrewer)

我们加载了3个包。这三个包都可以通过 install.packages() 直接安装。rgl是barplot3d依赖的包,RColorBrewer是为了配色用的。

画图:

先用baseR画个水水的箱线图,仅一行代码(这个算是base包里 boxplot() 的优点吧):

1boxplot(data, col = brewer.pal(4,"Dark2"))

箱线图

三维柱状图(3Dbarplot):

 1barplot3d(rows = 10, cols = 4#先根据数据构造一个画图矩阵
2          #画图要用的数据,必须是matrix类型
3          z = data %>% as.matrix(),
4          #展示角度,正面观
5          theta=30,
6          #展示角度,顶面观(出的图是可旋转的,所以这些都无关紧要)
7          phi=30,
8          #调整出图的高矮胖瘦的,挺重要!
9          scalexy=20,
10          #柱子(什么鬼)的侧面颜色,可调整透明度
11          sidecolors=brewer.pal(4,"Dark2"), alpha=0.4,
12          #顶面颜色
13          topcolors = brewer.pal(4,"Dark2"),
14          #x轴刻度标注,向量形式
15          xlabels = colnames(data),
16          #y轴刻度标注,向量形式
17          ylabels = rownames(data),
18          #z轴刻度,逻辑值
19          zlabels = TRUE)

出图如下:

3D barplot

这是个可以任意旋转的图,玩一玩~

转转看

再用barplot包里的测试数据画个“乐高图”:

1x=system.file("extdata""signature_probabilities.txt", package = "barplot3d")
2sigdata=read.table(x,header=TRUE,stringsAsFactors = FALSE)
3
4# Plot signature 2 without axis labels, with Sanger colors and some transparency so we can see all bars
5legoplot3d(contextdata=sigdata$Signature_8,
6           labels=FALSE,
7           scalexy=0.01,
8           sixcolors="sanger",
9           alpha=0.4)

lego plot






请到「今天看啥」查看全文


推荐文章
前端大全  ·  React+AI 技术栈(2025 版)
3 天前
商务河北  ·  经开区“美•强•优”三重奏
2 天前
新疆949交通广播  ·  一家三口特别的合影,网友全看哭了…
8 年前
环球时报  ·  美女老外在中国体验寒冬里送外卖
8 年前
同道大叔  ·  长得丑有什么好处?
8 年前
包容万象  ·  蒋介石儿子:中国人的官威太盛了
8 年前
CP头像集  ·  好好谈恋爱,别提什么一辈子。
7 年前