Altair简介
Altair是一个强大且简明的声明式统计可视化Python库,它能够快速绘制出各种优雅可交互的统计图表。
Altair基于一个前端图表库Vega-Lite,因此绘图的成果也可以通过 chart.to_json() 在前端项目中结合vega库使用。Vega-Lite是一套交互式图形语法,通过简洁的JSON键值对配置快速生成可视化结果,来支持数据分析工作。Altair可读作阿泰尔,天文学中指牵牛星、牛郎星,天鹰座中最明亮的恒星,用这个意象也表达了这个库的野望。
Altair的语法特点是:建立chart对象后,通过约定是什么图形(点、线、柱或其他)、轴域映射方式、颜色输出可视化图表。理念通关实践去理解,直接看绘图的框架。
基础绘图
Altair绘图代码框架如下:
1 | import altair as alt |
从上面的语句能看到的是其写法很像ggplot2、plotnine这类库,建立chart对象再声明图表类型和x、y轴数据映射,并可以用链式写法不断垒个性化配置上去,这也是声明式(declarative)语法的特点。通过 pip install altair
安装好Altair库之后,通过alt.Chart(df,width=400,height=300)
创建一个绘图对象,.mark_point()
表明是映射为散点图,散点图需要对应的x,y序列坐标,在.encode()
里声明,.interactive()
让输出的图表有基础的交互功能。
.encode()
对应的配置参数有:
- x: x轴的数据,水平方向数据序列;
- y: y轴的数据列表,对应竖直方向;
- size: 点状类型的半径,或其他类型的长度等;
- color: 图形元素的颜色,支持CSS颜色的各种写法,可以是一列也可以是一个16进制的字符串;
- opacity: 图元透明度,用的是opacity,不是alpha喔;
- shape: 点状元素的形状;
- tooltip: 鼠标放到图元上时显示的提示文本列;
- order: 声明图层顺序;
另外column和row是在分面时用的,根据选定的列进行分面的水平拆分和垂直拆分。
Altair更擅长画统计图表,因此下面的案例在数据方面全用数据框(DataFrame)格式进行实践。
同样的数据,同样的列映射到x轴和y轴,encode的写法是一致的,改变图表类型只需要.mark_point
变成.mark_line
绘制折线图。
从图中可以看出,Altair有好几种方法绘制出散点图,mark_point()统领散点图,而mark_circle()、mark_square()等和_point()
的不同之处在于circle限制了用圆形,而point是可通过size配置形状的。
Altair可以轻松地绘制出折线图及阶梯线图。
1 | alt.Chart(df,width=400,height=300).mark_line(color='#1EAFAE').encode( |
【Altair绘制折线图】 0-903-06-02-1.PNG
在mark_line里设置interpolate为step-after则折线图变阶梯线图。
1 | #所用到的数据集 |
【添加参数折线图变阶梯线】 0-903-06-03
将mark_line变成mark_bar是绘制柱图,包括柱状图和条形图。只需要互换x和y的映射赋值,可以实现条形图和柱状图的调换。因为默认的柱宽度比较小,画布宽度显得小了,在Chart对象里使用width参数声明图表整体宽度。
1 | alt.Chart(df,width=400).mark_bar().encode( |
【基础柱图 0-905-06-05-altair-1.PNG】
图中一个小细节是Fri.
在最前面,因为x轴默认进行了排序,这一点和plotnine很像,要保持原来的['Mon.','Tue.',...]
顺序,需要设置x轴的配置,那如何设置呢?先验知识是,在encode中,最简单的参数写法是.encode(x='x')
这种传入列名的写法,在Python中,一切皆是对象,Altair关于X轴对象封装为了altair.X(),因此另一种写法是.encode( x= alt.X('x'))
,故在altair.X()里可以设置排序顺序。
1 | alt.Chart(df,width=350).mark_bar(color='#1EAFAE').encode( |
【x轴按默认顺序的柱状图】
【0-905-06-06-altair-1.PNG】
alt.X里的sort参数可以取值为”ascending”、”descending”或者None。alt.X对象常用的配置参数还有:title(设置标题)、stack(堆叠图的起始偏移处)、aggregate(数据聚合方式,可以是sum、count、min等)
。完整的可视化信息图还需要配置文本标签、图例、标题等,Altair相关的参数也挺容易用。
1 | bar=alt.Chart(d1,width=400).mark_bar(color='#1EAFAE').encode( |
Altair还能绘制茎叶图,其他可视化库要绘制茎叶图挺复杂的甚至画不出来,而Altair能优雅画出。
【数据列轻松绘茎叶图】
统计制图
特别能体现Altair优雅的地方在于,x,y的映射可以包含汇总函数,例如对于一个二维的订单表,统计各月份单数绘制为柱状图,只需要把x赋值为month(order_time)
,令y的值为count()
即可。一个简单的例子如下,可视化展示df表中列k里各元素的出现次数。
1 | alt.Chart(df,width=300).mark_bar(color='#1EAFAE').encode( |
【在Altair里使用聚合运算】
【0-905-07-02-altair-1.PNG】
Altair内置了一些经典的数据科学数据集,封装在vega_datasets里,在使用pip安装Altair时也会同步安装上。下面通过著名的iris鸢尾花数据集展现Altair在统计制图方面的优势。
1 | from vega_datasets import data |
【绘制iris数据集的花萼宽度直方图】
0-905-07-03-altair-1.PNG
在alt.X和alt.Y中,还可以对数据集进行排序和筛选再绘图,很多处理细节都封装好了,调用起来写的语句可以很优雅。
通过配置以上提到的各种参数绘制出蝴蝶图,如下。
1 | left = alt.Chart(d1,height=230,width=270).encode( |
【蝴蝶图】
0-905-07-01-altair-1.PNG
分面
将一系列图排成一横排可以使用concat方法alt.concat(c1,c2)
,上图就用到了,或者使用更优雅的c1|c2
进行分面,而要实现上下排列的分面,使用c1&c2
。
1 | h=alt.Chart(iris,width=300).mark_bar(color='#1EAFAE').encode( |
【横向排列分面】
1 | df = data.cars() |
【一个挺完整的分面图】
【0-903-06-06-2.PNG】
除了对图表进行分面排列外,
组合多种类型的图到一个坐标系里也很重要。 在Altair中,|
和&
用于分面,而+
号用于把多个图表对象(alt.Chart)组合在一个坐标系里,组合图有两种写法,写法1是从头新建多个图表对象,最后用+号连接,写法2是公用一些配置,通过bar.mark_circle()
覆盖掉原先的mark_x
形成新的对象,再通过+号连接,这种写法通过公用一些属性再覆盖图的类型简化代码,两种写法的例子如下:
1 | bar= alt.Chart(d3).mark_bar(height=2).encode(x='y',y='x') |
【组合绘制棒棒糖图】
0-905-07-06-altair-1
要让Altair绘制的图具有交互性是很容易的(交互的细节都封装了,直接调用高差的方法就行),通过给图表对象加上.interactive()
便可获得基础的缩放和拖拽交互。而且在分面图里使用interactive之后,对其中的子图进行缩放,其他图也会联动缩放,非常实用。一些深入的交互功能可以通过封装的chart.add_selection()
、alt.selection_multi()
和.transform_filter()
等实现。一些细节是,在Altair中,散点图的交互,只有y轴缩放,x轴不变,而柱状图xy都会缩放,直方图则是只在x轴缩放,挺有趣的。
深入学习
一个成熟的可视化库都应该有定制主题进行颜色、图元的配置。在Altair中,定制主题的写法如下,很像直接写一个json对象。
1 | def lyns_marks(): |
Altair也支持地理信息的可视化,用Altair库画地图的示例代码如下,为了方便和容易复现,继续使用vega_datasets里的数据集。
1 | sphere = alt.sphere() |
【Altair绘制世界地图】
0-905-07-08-altair-1.PNG
将绘制的图表保存到本地可以用bar.save('altair_bar.html')
保存为HTML文档,保留着交互功能,要直接保存为PNG图片或PDF需要再安装一个altair_saver包,再调用bar.save('altair_bar.png')
。
总结
Altair是一个语法挺简洁、功能挺强大的Python可视化库,它封装了很多实用的方法用于统计数据的可视化,能用优雅的语法方便地对二维表格数据(代表格式是pandas的DataFrame)进行筛选分组汇总映射为各种图表类型,配置各种图元参数也很便捷,对地理空间数据支持也不错。可惜的是目前还没有支持饼图这一图表类型。
Altair基于Vega-lite套件封装的可视化功能,再底层是D3。在Vega体系里,封装的Python可视化库还有vincent及PdVega等。其中vincent在2016年之后就不再更新,其github页面上建议去了解Altair。而PdVega本身就和Altair关系密切,其文档的地址就是altair-viz.github.io/pdvega,很能说明问题,当然这两个库是差异化发展的,PdVega的特点是针对Jypyter Notebook环境进行了针对性的适配,并且API向pandas内置的plotting看齐。
在公众号后台回复 Altair 获取本文的xmind笔记和ipynb代码文件。
【Altair库思维导图 Altair可视化XMIND】
最后,用Altair绘制一个Altair的icon;
1 | d3=pd.DataFrame({'a':[0,10.1],'b':[0,100.2]}) |
【动图,gif 序列 01-2185-1】
参考资料: