饼图指北(Pie Chart)

Posted 玄魂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了饼图指北(Pie Chart)相关的知识,希望对你有一定的参考价值。

饼图是什么


饼图是一种圆形图表,通过将圆形划分为不同的扇区,通过扇区的面积来表达数值、比例或者频率的相对关系。
已知最早的饼图是 威廉·普莱菲 于1801年在他的《统计学摘要》Statistical Breviary中所作。


这张饼图,描述了1789年以前土耳其帝国在亚洲、欧洲及非洲中所占的比例。


饼图的基本组成

饼图



上图展示了一个基本的饼图的组成部分,最核心的部分就是“扇区”,这是饼图用来对数据进行编码的方式。

扇区(图片来源:https://miro.medium.com/max/1400/1*RsJx_V7JxWmqHtwYmTApcQ.png)


在上图中,通过 Arc、Angle 和 Surface 组成了一个扇区。

如何生成一个饼图
饼图的数据定义通常如下所示:

"values": [
                
                    "value": 335,
                    "name": "直接访问"
                ,
                
                    "value": 310,
                    "name": "邮件营销"
                ,
                
                    "value": 274,
                    "name": "联盟广告"
                ,
                
                    "value": 123,
                    "name": "搜索引擎"
                ,
                
                    "value": 215,
                    "name": "视频广告"
                
            ]


每条数据由一个分类字段和一个数值字段组成。数值字段要和每个扇区的角度对应上。分类数据和颜色进行映射。
角度计算实现逻辑很简单:
计算数值字段的总和-》计算每条数据的占比-》转化成角度(弧度)。

代码可以参考 d3.pie() (github.com/d3/d3-shape/)

function pie(data) 
    var i,
        n = (data = array(data)).length,
        j,
        k,
        sum = 0,
        index = new Array(n),
        arcs = new Array(n),
        a0 = +startAngle.apply(this, arguments),
        da = Math.min(tau, Math.max(-tau, endAngle.apply(this, arguments) - a0)),
        a1,
        p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
        pa = p * (da < 0 ? -1 : 1),
        v;

    for (i = 0; i < n; ++i) 
      if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) 
        sum += v;
      
    

    // Optionally sort the arcs by previously-computed values or by data.
    if (sortValues != null) index.sort(function(i, j)  return sortValues(arcs[i], arcs[j]); );
    else if (sort != null) index.sort(function(i, j)  return sort(data[i], data[j]); );

    // Compute the arcs! They are stored in the original data's order.
    for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) 
      j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = 
        data: data[j],
        index: i,
        value: v,
        startAngle: a0,
        endAngle: a1,
        padAngle: p
      ;
    

    return arcs;
  



分类颜色映射可以参考 d3.scaleordinal 方法 observablehq.com/@d3/d3


饼图的缺点及使用


在视觉层面,饼图是通过人眼对面积大小的对比来分析数据差异的。但是人眼对面积的识别精度要远远低于长度。所以饼图更适用于表达局部和整体之间的关系,而不是不同类别之间的对比。
整体和局部都要有意义

无整体意义的饼图


上图饼图单纯的用来进行类别的对比,但是总的百分比加起来并不等于100%,这会导致从直觉上获得的局部和整体的占比是错误的。
应用尽量少的分类
过多的分类会使得饼图的视觉效果趋于混乱。同样的数据,如果使用柱形图来显示,分类之间的对比就会明显很多。如图四。

过多类别信息的饼图



少量的分类数据更适合饼图。

尽量使用少量分类数据

有关资料显示,饼图使用的分类数最好不用超过5个,但是在现实应用中很少有人对此做限制。因为饼图的滥用,也会产生很多看似合理却难以解决的问题,比如饼图的标签布局(参考 可视化杂谈之饼图布局算法)。
分类数值的区分度尽可能高
如果各分类的数值比较接近,也不适合用饼图做对比,相同情况下,柱形图会有更好的表现。

分类数值的区分度低的饼图



饼图的变种


这里讲的饼图的变种,很多图只是和饼图类似,并不一定直接从饼图发展变化而来。


3D饼图

3D饼图


3D饼图通常只是视觉显示上增加了透视效果,给每块饼增加了厚度。由于透视的视角变换,会让扇区的面积和数值之间的比例关系更加失调,因此3D饼图在实际应用中受到大量的诟病。
有些工具也尝试让扇区的厚度具有数据意义,比如Excel 的3D饼图,可以配置厚度的字段映射。

厚度不一致的饼图(图片来源:https://img-blog.csdnimg.cn/img_convert/a25974f9110918ab8047c59899697305.png)



环形饼图

环形饼图


环形饼图又叫甜甜圈图,将普通饼图的中心位置预留出来,可以放置额外的数据信息。


玫瑰图

玫瑰图


玫瑰图又叫“极区图”,“鸡冠花图”,可以通过半径或者半径和角度的组合来进行数据映射。
玫瑰图最著名的应用是南丁格尔关于克里米亚战争中英国士兵死亡人数的描述。

南丁格尔的极坐标面积图:两幅图分别是 1854 年和 1855 年的军队伤亡人数,一年 12 个月恰好可以将极坐标分为 12 等分,每一瓣代表一个月。图中用颜色标记出了三种死亡原因。南丁格尔的重大贡献在于使得英国政府意识到真正影响战争伤亡的并非战争本身,而是由于军队缺乏有效的医疗护理,导致大量的士兵



旭日图


旭日图可以简单理解成饼图的嵌套结构,在表示数据比例关系的同时,可以表达层级和从属关系。
旭日图从数据结构上来看,本质上是树图,可以被认为是极坐标系下的矩形树图。

旭日图(图片来源:https://echarts.apache.org/examples/zh/editor.html?c=sunburst-drink)
旭日图数据关系(图片来源:https://datavizcatalogue.com/ZH/%E6%96%B9%E6%B3%95/%E6%97%AD%E6%97%A5%E5%9B%BE.html)


小结


饼图是可视化领域中使用频率最高的图表之一,也是最被滥用的图表之一。
本文对饼图的基本概念、使用场景及其扩展做了简要的介绍,希望对读者有所帮助。

以上是关于饼图指北(Pie Chart)的主要内容,如果未能解决你的问题,请参考以下文章

饼图指北(Pie Chart)

ECharts常用图表 饼图

tableau可视化函数使用案例(六十七)-Tableau饼图及其变种(环形图南丁格尔玫瑰图旭日图)

tableau可视化函数使用案例(六十七)-Tableau饼图及其变种(环形图南丁格尔玫瑰图旭日图)

python使用matplotlib可视化饼图(pie plot)可视化嵌套的环形饼图(Nested circular pie chart)

Python使用matplotlib可视化饼图为饼图添加标题和标签(Pie Chart)