作者 | 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制作的条形图
分解这个图表:
这就是使用Vega定义上述内容的方法:
{
"$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"关键字指定比例类型(默认为线性)。可以通过多种方式指定缩放域:
“axes”:[]
需要指定应该用于创建轴的方向和比例。可以使用很多属性来自定义它们。
“marks”:[]
使用标记来使用几何图元(矩形,圆形,线条等)对数据进行编码。在此条形图中,使用Rect标记。需要一个给定的位置,宽度和高度。还需要指定应该使用哪些数据来构建标记("from"属性)。
"from": {"data":"our_data"}
所有的东西一样的定义"x","y"以及"width"将来自该数据集。Vega Types起初可能看起来有些混乱,所以来看看这里使用的那些:
"x": {"scale": "xscale", "field": "category"}
"x"rects 的属性将通过将值从"category"字段传递给the来设置"xscale"。
"y": {"scale": "xscale", "band": 1}
"y"每个rect 的属性将是band scale的范围带宽xscale。
"fill": {"value": "steelblue"}
"fill"rects 的颜色将是steelblue。要定义常量值,使用该"value"属性。
Vega使用与d3 相同的输入,更新,退出模式:
“ 首次处理数据时会评估输入属性,并且会在场景中新添加标记实例。更新对于所有现有的(非出射)标记实例的属性进行评价。出口时背衬的标记中的数据被删除,并且因此标记在离开视觉场景属性被评估“
在"encode"属性中使用模式。在此条形图中,处理数据时放置元素:
"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转换按名称对项目进行排序:
"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轴的时间刻度和一个序数刻度来为矩形着色:
"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”:[]
在底部放置一个轴并在标签中显示年份:
"axes": [
{
"scale": "xScale",
"orient": "bottom",
"format": "%Y"
}
]
4 -“marks”:[]
有三个标记:矩形,矩形内的文本以及从每个矩形到轴的线。将使用"rect","text"并"rule"标记来定义它们。
但首先介绍一个重要的Vega属性:Signals。
❗Signals
信号是动态变量。正如文档所述,信号值是被动的:它们可以响应输入事件流,外部API调用或上游信号的变化而更新。在这里将使用它们的初始值,但它们的力量来自能够更新它们(将看到如何再次这样做)。
"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 ])
将指定的缩放变换(或投影)应用于指定的值。可选的组参数采用场景图组标记项来指示查找比例或投影的特定范围。
在这个例子中,将使用一个表达式将矩形放置在每年中间,并使用以下表达式:
"signal": "scale('xScale',datum.release)-rectWidth/2"
//scale(name, value[,group]
需要指定应该使用哪些数据来构建带有"from"属性的标记。可以从另一个标记本身指定数据!在这种情况下,将使用rect标记中的数据,这样就可以获得每个矩形的中心并将文本放在中间。要访问"datum"在表达式中使用的数据点。
"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”:[]
图例定义与标记定义类似。要自定义是可寻址的元素是:
这里只设置"x"图例的位置(整个组)并为标题和标签设置fontSize。
"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值来设置一个可视化的主题。这里设置图形文本的字体。该标题指令增加了一个描述性标题的图表。
"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编辑器中查看所有示例。