前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vega的交互式数据可视化

Vega的交互式数据可视化

作者头像
代码医生工作室
发布2019-06-21 17:17:19
3.5K0
发布2019-06-21 17:17:19
举报
文章被收录于专栏:相约机器人相约机器人

作者 | DéborahMesquita

来源 | Towards Data Science

编辑 | 代码医生团队

一直在学习新的可视化工具,因为这有助于找到适合手头任务的正确工具。在数据可视化方面,d3通常是首选,最近一直在用Vega。

https://vega.github.io/vega/

Vega引入了可视化语法。语法基本上是一组规定如何使用语言的规则,因此可以将Vega视为一种工具,它定义了一组如何构建和操纵视觉元素的规则。

随着对数据可视化的经验不断增长,发现越来越多的约束是一件好事。通过引入可视化语法,Vega提供了一些限制。关于它的最好的事情是 这些约束可以在构建数据可视化时感觉非常高效。

Vega-Lite也是一种高级语法,专注于快速创建常见的统计图形,今天将坚持使用Vega,这是一种更通用的工具。

来看看Vega的工作原理。

Vega概述

可以在Web上部署Vega,但在本教程中将简单地使用Vega编辑器。

使用Vega时,在JSON对象中定义可视化。开始构建一个条形图。

用Vega制作的条形图

分解这个图表:

  • 数据(每个数据点的类别和数量)
  • X轴,每个类别都被容纳(需要一个比例来说明每个类别应该放置)
  • y轴,显示每个数据点的数量(需要一个比例来说明应该放置每个数量)
  • 矩形

这就是使用Vega定义上述内容的方法:

代码语言:javascript
复制
{

  "$schema": "https://vega.github.io/schema/vega/v5.json",

  "width": 400,

  "height": 200,

  "padding": 5,

  "data": [

    {

      "name": "our_data",

      "values": [

        {

          "category": "A",

          "amount": 28

        },

        {

          "category": "B",

          "amount": 55

        },

        {

          "category": "C",

          "amount": 43

        }

      ]

    }

  ],

  "scales": [

    {

      "name": "xscale",

      "type": "band",

      "domain": {

        "data": "our_data",

        "field": "category"

      },

      "range": "width",

      "padding": 0.05

    },

    {

      "name": "yscale",

      "domain": {

        "data": "our_data",

        "field": "amount"

      },

      "range": "height"

    }

  ],

  "axes": [

    {

      "orient": "bottom",

      "scale": "xscale"

    },

    {

      "orient": "left",

      "scale": "yscale"

    }

  ],

  "marks": [

    {

      "type": "rect",

      "from": {

        "data": "our_data"

      },

      "encode": {

        "enter": {

          "x": {

            "scale": "xscale",

            "field": "category"

          },

          "width": {

            "scale": "xscale",

            "band": 1

          },

          "y": {

            "scale": "yscale",

            "field": "amount"

          },

          "y2": {

            "scale": "yscale",

            "value": 0

          },

          "fill": {

            "value": "steelblue"

          }

        }

      }

    }

  ]

}

可以在这里试试。

https://vega.github.io/editor/#/url/vega/N4KABGBEAkDODGALApgWwIaQFxUQFzwAdYsB6UgN2QHN0A6agSz0QFcAjOxge1IRQyUa6SgFY6AK1jcAdpAA04KAHdGAExbYwAFgAMuxREgpG1fFoBM+w1ELo1axjOpbRipZDXo8mHAG0lCFAIEKgZdFRkLUgfdgAbKJtQyAp0ONZkWC0A0NDgSHhvGm4AJwBPaIBBBSgI7lYZPEsADgBfJNz8wrxi8uiAIRrIOoamnFFRdsDOgqLqUoqcSABhIZHGrW0AZlbpiABdad2D9yMENMzs6eDcyHDI6IAPc4SFPag8MsIopfZ0GTUb1yUDU3AwTi0+S8PmisVe8igADNGMg4oClt1ehUpsDICV-tQfip1JoOkY7A4nC4cLo6LpREcOjdkvciZAyi9Eu9PGD0BCcFDvL4Puh4okkSi0dF1k0cbd8c42SYzE0jkp9qdao9Lv5rlBSiiNr9uAQwUNOU8LWA5UF9SVDWMoAlEU0EZALUsOYVXtb1ZrIBgSgBrLK6vLcz7faIlZDwV3cxElM0CzxC7AxUWvG0hSDIGTwbhqInM255nolSHvZKPSHu71s571obI1HoqCY+Z9bO41QaRC1j1QRsXIZ-AFaACM3duizA+UH7ItbpbUqWMsg0+SZQsA6bnqXUFS6SJuk3OeRcTitaPGWisB6qPit+OwN9wJfEBfh1aQA

来看看这些定义中的每一个。在这里简要解释一下,可以使用更多属性来定制事物。

“data”:[]

可以直接在规范中定义数据(比如正在使用"values"属性)或使用属性从外部文件(例如json或csv)加载数据"url"。

“scales”:[]

Vega scales由d3级库提供。使用"type"关键字指定比例类型(默认为线性)。可以通过多种方式指定缩放域:

  • 一个数据引用对象,它指定一个或多个数据集中的字段值,就像正在使用的那样{"data": "our_data", "field": "amount"}。Vega 从数据集计算密钥的[min,max]数组amount
  • 作为域值的字面数组
  • 信号参考解析为一个域值数组。例如,{"signal": "myDomain"}

“axes”:[]

需要指定应该用于创建轴的方向和比例。可以使用很多属性来自定义它们。

“marks”:[]

使用标记来使用几何图元(矩形,圆形,线条等)对数据进行编码。在此条形图中,使用Rect标记。需要一个给定的位置,宽度和高度。还需要指定应该使用哪些数据来构建标记("from"属性)。

代码语言:javascript
复制
"from": {"data":"our_data"}

所有的东西一样的定义"x","y"以及"width"将来自该数据集。Vega Types起初可能看起来有些混乱,所以来看看这里使用的那些:

代码语言:javascript
复制
"x": {"scale": "xscale", "field": "category"}

"x"rects 的属性将通过将值从"category"字段传递给the来设置"xscale"。

代码语言:javascript
复制
"y": {"scale": "xscale", "band": 1}

"y"每个rect 的属性将是band scale的范围带宽xscale。

代码语言:javascript
复制
"fill": {"value": "steelblue"}

"fill"rects 的颜色将是steelblue。要定义常量值,使用该"value"属性。

Vega使用与d3 相同的输入,更新,退出模式:

“ 首次处理数据时会评估输入属性,并且会在场景中新添加标记实例。更新对于所有现有的(非出射)标记实例的属性进行评价。出口时背衬的标记中的数据被删除,并且因此标记在离开视觉场景属性被评估“

在"encode"属性中使用模式。在此条形图中,处理数据时放置元素:

代码语言:javascript
复制
"encode": {

    "enter": {

        "x": {"scale": "xscale", "field": "category"},

        "width": {"scale": "xscale", "band": 1},

        "y": {"scale": "yscale", "field": "amount"},

        "y2": {"scale": "yscale", "value": 0},

        "fill": {"value": "steelblue"}

     }

}

为了更好地了解Vega能够构建时间线图表。

与Vega建立时间表

使用Vega构建的时间轴

使用一些Vega属性来构建时间轴

1 -“data”:[]

除了加载数据,还可以使用Vega Transforms过滤,计算新字段或派生新数据流。可以使用collect转换按名称对项目进行排序:

代码语言:javascript
复制
"data": [

    {

      "name": "libraries",

      "format": {

        "type": "json",

        "parse": {

          "release": "date:'%Y'"

        }

      },

      "values": [

        {

          "name": "vega",

          "release": "2013",

          "license": "BSD 3-Clause",

          "description": "Vega is a visualization grammar, a declarative language for creating, saving, and sharing interactive visualization designs"

        },

        {

          "name": "d3",

          "release": "2011",

          "license": "BSD 3-Clause",

          "description": "D3 (Data-Driven Documents or D3.js) is a JavaScript library for visualizing data using web standards"

        },

        {

          "name": "plotly",

          "release": "2012",

          "license": "MIT",

          "description": "Plotly.js is an open source JavaScript library for creating graphs and dashboards"

        }

      ],

      "transform": [

        {

          "type": "collect",

          "sort": {

            "field": "name"

          }

        }

      ]

    }

  ]

Vega的另一个好处是可以检查用来构建可视化的所有数据的内容:

按名称排序的数据集

2-“scales”:[]

需要一个x轴的时间刻度和一个序数刻度来为矩形着色:

代码语言:javascript
复制
"scales": [

    {

      "name": "xScale",

      "type": "time",

      "domain": {

        "data": "libraries",

        "field": "release"

      },

      "range": "width",

      "nice": "year"

    },

    {

      "name": "colorScale",

      "type": "ordinal",

      "domain": {

        "data": "libraries",

        "field": "license"

      },

      "range": {

        "scheme": "dark2"

      }

    }

  ]

3-“axes”:[]

在底部放置一个轴并在标签中显示年份:

代码语言:javascript
复制
"axes": [

    {

      "scale": "xScale",

      "orient": "bottom",

      "format": "%Y"

    }

  ]

4 -“marks”:[]

有三个标记:矩形,矩形内的文本以及从每个矩形到轴的线。将使用"rect","text"并"rule"标记来定义它们。

但首先介绍一个重要的Vega属性:Signals。

❗Signals

信号是动态变量。正如文档所述,信号值是被动的:它们可以响应输入事件流,外部API调用或上游信号的变化而更新。在这里将使用它们的初始值,但它们的力量来自能够更新它们(将看到如何再次这样做)。

代码语言:javascript
复制
"signals": [

    {

      "name": "rectWidth",

      "value": 50

    },

    {

      "name": "rectHeight",

      "value": 40

    },

    {

      "name": "rectY",

      "value": 85

    },

    {

      "name": "rectCenter",

      "init": "[rectWidth/2,rectY+rectHeight/2]"

    }

  ]

现在有信号,可以使用它们来放置标记。信号也可以保存Vega 表达式。一个非常常用的是规模:

scale(name,value [,group ])

将指定的缩放变换(或投影)应用于指定的值。可选的组参数采用场景图组标记项来指示查找比例或投影的特定范围。

在这个例子中,将使用一个表达式将矩形放置在每年中间,并使用以下表达式:

代码语言:javascript
复制
"signal": "scale('xScale',datum.release)-rectWidth/2"

         //scale(name, value[,group]

需要指定应该使用哪些数据来构建带有"from"属性的标记。可以从另一个标记本身指定数据!在这种情况下,将使用rect标记中的数据,这样就可以获得每个矩形的中心并将文本放在中间。要访问"datum"在表达式中使用的数据点。

代码语言:javascript
复制
"marks": [

    {

      "type": "rect",

      "name": "rectangles",

      "from": {

        "data": "libraries"

      },

      "encode": {

        "enter": {

          "width": {

            "signal": "rectWidth"

          },

          "height": {

            "signal": "rectHeight"

          },

          "x": {

            "signal": "scale('xScale',datum.release)-rectWidth/2"

          },

          "y": {

            "signal": "rectY"

          },

          "fill": {

            "signal": "scale('colorScale', datum.license)"

          },

          "tooltip": {

            "signal": "{'Description': datum.description}"

          }

        },

        "update": {

          "fillOpacity": {

            "value": 1

          }

        },

        "hover": {

          "fillOpacity": {

            "value": 0.5

          }

        }

      }

    },

    {

      "type": "text",

      "name": "labels",

      "from": {

        "data": "rectangles" // ⬅️cool

      },

      "encode": {

        "enter": {

          "text": {

            "signal": "datum.datum.name"

          },

          "x": {

            "signal": "datum.x+rectCenter[0]" //datum.x is from rect

          },

          "y": {

            "signal": "rectCenter[1]"

          },

          "align": {

            "value": "center"

          },

          "baseline": {

            "value": "middle"

          },

          "fontWeight": {

            "value": "bold"

          },

          "fill": {

            "value": "black"

          }

        }

      },

      "interactive": false

    },

    {

      "type": "rule",

      "from": {

        "data": "labels" // ⬅️cool

      },

      "encode": {

        "enter": {

          "x": {

            "signal": "datum.x"

          },

          "x2": {

            "signal": "datum.x"

          },

          "y": {

            "signal": "datum.y+rectCenter[0]-5"

          },

          "y2": {

            "signal": "height"

          },

          "strokeWidth": {

            "value": 2

          }

        }

      }

    }

  ]

5 -“legends”:[]

图例定义与标记定义类似。要自定义是可寻址的元素是:

  • legend对于图例组标记,
  • title对于标题文字标记,
  • labels对于标签文字标记,
  • symbols对于图例符号标记,
  • entries对于包含符号/标签对的符号图例组标记,以及
  • gradient对于渐变矩形标记:一个带有渐变填充的矩形用于连续渐变图例,多个矩形标记带有用于离散渐变图例的实心填充。

这里只设置"x"图例的位置(整个组)并为标题和标签设置fontSize。

代码语言:javascript
复制
"legends": [

    {

      "title": "License",

      "fill": "colorScale",

      "orient": "none",

      "encode": {

        "title": {

          "update": {

            "fontSize": {

              "value": 15

            }

          }

        },

        "labels": {

          "update": {

            "fontSize": {

              "value": 12

            }

          }

        },

        "legend": {

          "update": {

            "x": {

              "value": 500

            }

          }

        }

      }

    }

  ]

6 -“config”和“title”:[]

该配置对象定义默认的Visual值来设置一个可视化的主题。这里设置图形文本的字体。该标题指令增加了一个描述性标题的图表。

代码语言:javascript
复制
"config": {

    "text": {

      "font": "Ideal Sans, Avenir Next, Helvetica"

    },

    "title": {

      "font": "Ideal Sans, Avenir Next, Helvetica",

      "fontWeight": 500,

      "fontSize": 17,

      "limit": -1

    },

    "axis": {

      "labelFont": "Ideal Sans, Avenir Next, Helvetica",

      "labelFontSize": 12

    }

  },

"title": {

    "text": "Data visualization tools release dates",

    "orient": "top",

    "anchor": "start",

    "frame": "group",

    "encode": {

      "update": {

        "dx": {

          "value": -1

        }

      }

    }

  }

完成了!可以在这里看到代码。

https://github.com/dmesquita/vega-timeline-tutorial

在本教程中没有看到其他一些很酷的Vega功能:

  • 触发:修改数据集或标记属性以响应信号值
  • 预测:用于绘制地图(经度,纬度)数据的制图投影
  • 事件流:定义输入事件流以指定交互
  • 布局:对一组组标记执行网格布局

最后的评论

今天在工作流程中使用Vega来构建和测试关于数据可视化选择的假设。如果在那之后发现需要更多定制的东西,那么将改变齿轮并使用d3。

查看更多Vega示例:

https://vega.github.io/vega/examples/

可以在在线Vega编辑器中查看所有示例。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 相约机器人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档