美文网首页tableau技能tableau
Tableau可视化练习(POINT图表竞赛):漫威英雄能力值(

Tableau可视化练习(POINT图表竞赛):漫威英雄能力值(

作者: 有理酱_Yuri_Wg | 来源:发表于2019-05-01 21:36 被阅读152次
    能力值 排名

    工作簿在此:Tableau Public: Marvel_SuperHeros
    这次主要挑战了一下Tableau制作雷(zhen)达(ma)图(fan)和放射条形图!!!
    不过还是硬着头皮死磕到底。。。所幸最后总算成功了,效果还算满意~~~
    整个流程分三步:
    观察数据 > 数据预处理 > 可视化

    数据准备阶段,Python小白顺便拿这次的数据练练手

    一、观察/理解数据

    import numpy as np
    import pandas as pd
    df=pd.read_csv('Superheroes.csv')
    df.head()
    
    Name Attribute Name Gender Value
    0 Black Widow Agility 0 14
    1 Elektra Agility 0 16
    2 Invisible Woman Agility 0 12
    3 Storm Agility 0 14
    4 Black Widow Fighting Skills 0 76
    #查看一下数据框的详细信息
    df.info()
    
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 180 entries, 0 to 179
    Data columns (total 4 columns):
    Name              180 non-null object
    Attribute Name    180 non-null object
    Gender            180 non-null int64
    Value             180 non-null int64
    dtypes: int64(2), object(2)
    memory usage: 8.5+ KB
    
    #看看有多少个英雄
    df['Name'].describe()
    
    count                 180
    unique                 30
    top       Captain America
    freq                    6
    Name: Name, dtype: object
    
    #Attribute Name中的唯一值
    list(df['Attribute Name'].unique())
    
    ['Agility', 'Fighting Skills', 'Height', 'Intelligence', 'Speed', 'Strength']
    
    #数据透视表来一个
    df.pivot_table(index='Name',columns='Attribute Name',values='Value').describe()
    
    Attribute Name Agility Fighting Skills Height Intelligence Speed Strength
    count 30.000000 30.000000 30.00000 30.000000 30.000000 30.000000
    mean 15.200000 71.233333 181.70000 4.933333 6.000000 36.400000
    std 3.397768 8.605064 8.55066 1.964045 3.877432 15.612992
    min 10.000000 55.000000 165.00000 3.000000 1.000000 15.000000
    25% 12.000000 64.250000 177.25000 3.000000 3.250000 26.000000
    50% 14.000000 71.500000 181.00000 4.000000 4.500000 29.500000
    75% 17.750000 77.750000 185.75000 7.000000 8.750000 44.750000
    max 22.000000 85.000000 205.00000 9.000000 16.000000 81.000000
    • 数据很完整,没有缺失
    • 根据这些数据,可以考虑利用雷达图来展现每个超级英雄的能力图谱。
    • 根据常识判断,每种能力属性的单位不同,且从最后的透视表结果可以看出,数值范围也有很大差距,因此需要对这些数值进行标准化处理。
      Agility:10-22
      Fighting Skills:55-85
      Height:165-205
      Intelligence:3-9
      Speed:1-16
      Strength:15-81

    二、数据预处理

    数据没有大问题,跳过数据清洗阶段,直接进入数据加工阶段,这一阶段主要就是进行数据计算,对“Value”这一度量进行标准化处理。

    常见的标准化方法有:min-max标准化(Min-max normalization),log函数转换,atan函数转换,z-score标准化(zero-mena normalization,此方法最为常用),模糊量化法。本文只介绍min-max法(规范化方法)。

    极差标准化法,是消除变量量纲和变异范围影响最简单的方法。
    具体的操作方法为:首先需要找出该指标的最大值(Xmax)和最小值(Xmin),并计算极差(R = Xmax - Xmin),然后用该变量的每一个观察值(X)减去最小值(Xmin),再除以极差(R),即:X' = (X-Xmin) / (Xmax-Xmin)

    经过极差标准化方法处理后,无论原始数据是正值还是负值,该变量各个观察值的数值变化范围都满足0≤X'≤1,并且正指标、逆指标均可转化为正向指标,作用方向一致。但是如果有新数据加入,就可能会导致最大值(Xmax)和最小值(Xmin)发生变化,就需要进行重新定义,并重新计算极差(R)。

    用Python进行标准化计算:(Python小白想不出好的写法了,先将就着用用)

    #从透视表里提取每个能力值的max和min
    mm=df.pivot_table(index='Name',columns='Attribute Name',values='Value').describe()
    
    df['V_N']=None
    bool=(df['Attribute Name']=='Agility')
    df['V_N'][bool]=df.Value[bool].apply(lambda x: (x-mm['Agility']['min'])/(mm['Agility']['max']-mm['Agility']['min']))
    
    bool=(df['Attribute Name']=='Fighting Skills')
    df['V_N'][bool]=df.Value[bool].apply(lambda x: (x-mm['Fighting Skills']['min'])/(mm['Fighting Skills']['max']-mm['Fighting Skills']['min']))
    
    bool=(df['Attribute Name']=='Height')
    df['V_N'][bool]=df.Value[bool].apply(lambda x: (x-mm['Height']['min'])/(mm['Height']['max']-mm['Height']['min']))
    
    bool=(df['Attribute Name']=='Intelligence')
    df['V_N'][bool]=df.Value[bool].apply(lambda x: (x-mm['Intelligence']['min'])/(mm['Intelligence']['max']-mm['Intelligence']['min']))
    
    bool=(df['Attribute Name']=='Speed')
    df['V_N'][bool]=df.Value[bool].apply(lambda x: (x-mm['Speed']['min'])/(mm['Speed']['max']-mm['Speed']['min']))
    
    bool=(df['Attribute Name']=='Strength')
    df['V_N'][bool]=df.Value[bool].apply(lambda x: (x-mm['Strength']['min'])/(mm['Strength']['max']-mm['Strength']['min']))
    df.head(10)
    
    #算个百分制,看着比较舒服
    df['V_N*100']=df['V_N'].apply(lambda x: round(x*100))
    df.head()
    
    Name AttributeName Gender Value V_N V_N*100
    0 Black Widow Agility 0 14 0.333333 33
    1 Elektra Agility 0 16 0.500000 50
    2 Invisible Woman Agility 0 12 0.166667 17
    3 Storm Agility 0 14 0.333333 33
    4 Black Widow Fighting Skills 0 76 0.700000 70

    当然简单的方法有很多,我这儿纯粹是练习Python用的,下面进入可视化环节~

    三、可视化

    Tableau雷达图的制作可以参考这里:用Tableau画雷达图
    放射条形图可以参考这个:用花型射线图 Radial Chart 对比数据
    磨刀不误砍柴功——弄清楚基本概念
    有时候总是觉得为什么tableau这么复杂,有些图表连excel都超容易出。很多时候发现自己都在凭感觉作图,而事实上却连最基本的概念“维度”,“度量”,“连续”,“离散”都还没搞清楚。所以,磨刀不误砍柴工,我还是决定自己一边详细地理一理概念,一边总结一下制作步骤。
    雷达图
    你看的的雷达图不只是一张图,其实是由三张工作表叠加而成

    1、同心六边形

    构建六边形,关键在于要在直角坐标系中确定六边形6个顶点的位置。
    其实就是一道数学题:已知圆心(x0,y0),半径r,角度a,求圆上的点坐标:假设圆上任一点为(x1,y1),则
    x1 = x0 + r * cos( a )
    y1 = y0 + r * sin( a )

    所以在这里我们可以:
    -圆心默认为直角坐标系原点(0,0);
    -六边形外接圆半径[R]可以自定义;
    -6个顶点在圆上的角度分别为:0',60',120',180',240',300',360'
    -6个顶点的直角坐标就可以根据以上数据在Tableau中创建以下两个计算字段求得:
    · [sin]=SIN([point]PI()/180)[R]
    · [cos]=COS([point]PI()/180)[R]

    • 构造数据集
      根据以上思路,就可以构造创建同心六边形的数据集了,最终的同心六边形完整的数据集如下图
    • Tableau拖拉拽进行曲
      把sin和cos两个度量拖到视图上,出来两个坐标轴和一个点,为什么?


    官方文档:
    当您第一次连接到数据源时,Tableau 会将包含离散分类信息的任何字段(例如,值为字符串或布尔值的字段)分配给“数据”窗格中的“维度”区域。
    当您单击并将字段从“维度”区域拖到“行”或“列”时,Tableau 将创建列或行标题。
    当您第一次连接到数据源时,Tableau 会将包含定量数值信息的任何字段(即其中的值为数字的字段)分配给“数据”窗格中的“度量”区域。
    当您将字段从“度量”区域拖到“行”或“列”时,Tableau 将创建连续轴。

    所以那一点代表了所有点聚合的结果,当然这里我不想要它们聚合,所以这里需要右击sin和cos将其设置成维度。
    先将cos设置成维度,可以发现视图发生了变化


    再将sin设置成维度,视图再一次发生了变化,也离同行六边形越来越近了

    接下去试着把标记类型改为线条,可以发现所有的点都被视为一个对象连成了一条线

    而我们需要的其实是5条独立的线组成的5个六边形,这时候把[六边形]维度拖到标记里,来对每一组顶点予以区分,得到的结果如下图,确实产生了5组独立的连线,但是点之间连接的顺序还有些问题

    记得在开始创建数据时有一个[point]字段,依此记录了每一个点的角度值,将它作为标记的路径拖进来,可以看到[point]默认为聚合,所有点又连成了一个整体

    最后一步:将[point]设置为维度,要构造的同心六边形就形成啦~

    针对度量和维度,我们了解了基础概念,同时特别要注意的点:
    -离散字段创建标题、连续字段创建连续轴
    -辨别视图中的字段是度量还是维度的依据在于该字段是否已聚合
    -维度和度量是可以相互转化的
    -离散字段和连续字段也是可以相互转化的
    -维度/度量和离散/连续不是必然对应的

    2、放射线

    先看一下最终成图以及数据摘要和完整数据


    “完整数据”中是需要构建的最原始的数据集,思路跟创建六边形类似
    最关键的就是计算弧度和半径R,从而确定几个点的直角坐标
    先看一下几个重要的计算字段:

    • 弧度计算
      [angle]=2 * PI() * (INDEX()-1) * (1/WINDOW_COUNT(COUNT([数值])))
      其实这是个通用公式,在数据量大时尤其好用,构造6条射线这种情境下有点“杀鸡焉用宰牛刀”的感觉,其实大可以这样算2 * PI() * (INDEX()-1) * (1/6)。
      但是想要一劳永逸,当然要一开始就突破难点啦~
      所以还是不要偷懒,先琢磨透原理吧~
      (对了,ps.[数值]列类似于辅助列,数值可以自由设定)
      1/WINDOW_COUNT(COUNT([数值]))可以理解为将圆切分成几个等份,每个占据1/6份
      (INDEX()-1) * (1/WINDOW_COUNT(COUNT([数值]))),将数值代入看看:
      (1-1) * (1/6)=0;
      (2-1) * (1/6)=1/6;......
      结果依此是:0,1/6,2/6......5/6
      2 * PI() * (INDEX()-1) * (1/WINDOW_COUNT(COUNT([数值])))的结果就是得到每个点的弧度

    • 半径计算
      [R]=IIF(ATTR([内外环])= 0, 0, SUM([数值])/WINDOW_MAX(SUM([数值])))
      依然是一个通用公式,适用于构建放射条形图(每条线半径不同的情况),这里也可以简单化处理直接IIF(ATTR([内外环])= 0, 0, 1)
      如果是内环,半径为0;
      如果是外环,则进行归一化处理,处理后也可以乘以一个系数100,让数字看起来好看一点

    • 计算直角坐标
      [sin]=SIN([angle]) * [R]
      [cos]=COS([angle]) * [R]

    造好数据以后就是拖拉拽啦~
    (计算字段的命名可能跟图上显示的有些出入,大家意会一下,其实计算字段可以整合的更简单一些,现在有很多冗余,下次改进)
    [sin]和[cos]先拽进来,发现是只有一个空值,为什么?

    看看半径的计算公式里有个条件判断IIF(ATTR([内外环])= 0, ...)
    试试把[内外环]拽到标记里并且设置成维度,有动静了~

    再把[线角度]拖到标记栏,设置成维度,作为[sin]和[cos]的“计算依据”,这里应该是用到了分区计算的概念 ,提一下

    基于“区”的计算
    计算依据中的“区”,就是指视图中的子视图或子数据表,在计算时,“区”不像“表”那样贯穿到边(底),而是根据分组,在分组中进行独立计算。
    基于“表”的计算
    计算依据中的“表”,就是指视图中的整个数据表,不论其计算方向是横向、纵向、横穿然后向下、向下然后横穿中的哪一种,其计算可以理解贯穿到边(底)。
    基于“单元格”的计算
    最特殊的一种,每个单元格只与自己进行计算,与其它单元格均无联系

    点就出来啦~

    接着把标记类型改为“线”,再把[内外环]作为路径依据,6条线就出来啦~

    3、面积图(不规则六边形)

    开始造吧!
    目标依旧是计算得到每个点的直角坐标

    罗列一下用到的几个函数:
    1、数字函数:
    PI( ):返回数字常量 pi:3.14159。
    SIN(number):返回角度的正弦。以弧度为单位指定角度。
    COS(number):返回角度的余弦。以弧度为单位指定角度。
    示例:COS(PI( ) /4)
    2、聚合函数:
    ATTR(expression):如果它的所有行都有一个值,则返回该表达式的值。否则返回星号。会忽略 Null 值。
    COUNT(expression):返回组中的项目数。不对 Null 值计数。
    SUM(expression):返回表达式中所有值的总计。SUM 只能用于数字字段。会忽略 Null 值。
    3、逻辑函数:
    IIF(test, then, else, [unknown]):检查某个条件是否得到满足,如果为 TRUE 则返回一个值,如果为 FALSE 则返回另一个值,如果未知,则返回可选的第三个值或 NULL。
    4、表计算函数:
    INDEX( ):返回分区中当前行的索引,不包含与值有关的任何排序。第一个行索引从 1 开始。
    WINDOW_COUNT(expression, [start, end]):返回窗口中表达式的计数。窗口用与当前行的偏移定义。使用 FIRST()+n 和 LAST()-n 表示与分区中第一行或最后一行的偏移。如果省略了开头和结尾,则使用整个分区。
    WINDOW_SUM(expression, [start, end]):返回窗口中表达式的总计。窗口用与当前行的偏移定义。使用 FIRST()+n 和 LAST()-n 表示与分区中第一行或最后一行的偏移。如果省略了开头和结尾,则使用整个分区。

    偷个小懒,回补~

    相关文章

      网友评论

        本文标题:Tableau可视化练习(POINT图表竞赛):漫威英雄能力值(

        本文链接:https://www.haomeiwen.com/subject/vxsunqtx.html