Python交互式数据可视化——酷炫的Altair库
本文作者:温和铭,中南财经政法大学统计与数学学院
本文编辑:周一鸣
技术总编:王玉婷
Stata and Python 数据分析
由李春涛教授和团队成员司海涛、薛原编写的《Stata正则表达式及其在财务数据中的应用》终于和大家见面啦!爬虫俱乐部特此为大家准备了100本,即日起购买爬虫俱乐部课程,可赠送本书一本,先到先得!
购书链接:
提到利用Python实现数据的可视化,你首先想到的是什么?在之前的推文中,我们已经为大家介绍过耳熟能详的一些Python数据可视化库,比如Pyecharts:《Python数据可视化神器:pyecharts (一)》、《Python数据可视化神器:pyecharts (二)》;Seaborn:《【数据可视化】统计图绘制神器:Seaborn》、Matplotlib:《数据可视化利器——Matplotlib》等,这些都能满足大家在绘制统计图表时的基本需求。但是,由于以上的库使用者众多,大家画出来的图往往大同小异,难免使人“视觉疲劳”。今天,我们介绍一个虽然稍显“冷门”,但拥有强大交互式功能、配色清新的数据可视化库——Altair,让你的统计图表从茫茫图海中脱颖而出。
Altair库是由华盛顿大学的数据科学家Jake Vanderplas编写的第三方库,提供强大而简洁的可视化语法,我们可以在官方文档的示例画廊(https://altair-viz.github.io/gallery/index.html)中,了解Altair库都能实现哪些图像的绘制。除了各类散点图、条形图、折线图、饼图和地图之外,Altair还能画出许多精美的交互式图表。
首先,我们需要安装Altair库,使用win+R
快捷键打开cmd,可输入以下两种安装命令:
#安装Altair
pip install altair vega_datasets #使用pip安装
conda install -c conda-forge altair vega_datasets #在anaconda的命令行中安装
import altair as alt
让我们先来了解一下Altair的基础语法结构,在Altair中,altair.Chart()是基本的图表对象,一般而言,我们使用DataFrame作为画图对象,定义一个图表对象的语法如下例:
import pandas as pd
data = pd.DataFrame({'a': list('ABCDEFGHI'),
'b': [8, 4, 6, 9, 3, 5, 2, 4, 7]})
chart = alt.Chart(data)
这里我们定义的图表对象为chart
,接着可以指定数据的展示方式。常用语句如下:
mark_point():散点图
mark_line():折线图
mark_bar():柱状图
mark_geoshape():地理地图
在画图时,我们还需要声明Chart中哪些数据是x轴,哪些是y轴。在Altair中,我们可以通过调用Chart对象的encode()方法,往里面传递参数来对x轴、y轴等进行设置,沿用上例中创建的数据集:
alt.Chart(data).mark_point().encode(x='a', y='b') #定义x轴为a,y轴为b,画散点图
以上就是使用Altair库画图的基础“三件套”:一是通过alt.Chart()指定画图要用到的数据集;二是通过mark_XX()指定所要画出的图形类型,其中XX需要替换成图形名称,如point、line、bar等等;三是通过encode()定义图形中的坐标轴,一般是x轴和y轴。记住这三个组成部分,我们就已经掌握了Altair的基本语法。
在了解一些Altair库中的基础语法后,让我们使用真实数据,进行画图实操。这里使用到的是我国股票市场中较为常见的几个股票指数,上证综合指数(000001)、深证综合指数(399106)、沪深300(000300)在2018年10月31日至2022年10月31日的开盘指数、最高指数、最低指数、收盘指数以及指数回报率指标,数据均来源于国泰安CSMAR数据库。
首先调取Altair和Pandas库,导入数据:
import pandas as pd
import altair as alt
data=pd.read_excel('股指.xlsx')
接下来,我们可以针对其中的一些指标进行画图分析,观察数据的总体分布情况,这里以绘制最高指数的刻度线图和直方图为例:#刻度线图
alt.Chart(data).mark_tick().encode(
x='最高指数'
).properties(
title="刻度线图"
)
#直方图
alt.Chart(data).mark_bar().encode(
alt.X('最高指数', bin=True),
y='count()'
).properties(
title="直方图"
)
在画图时,我们可以使用properties(title=" ")这一选项为图片添加标题,最终输出效果如下:
除此之外,由于数据集中包含了年-月-日信息,我们还可以提取特定的年份,通过热力图来观察不同月份-日期组合之间的数据分布差异,以提取2022年1月-10月的数据为例:
#提取月份和日期看指数回报率
data2022 =data[(data['交易日期'] >= '2022-01-02') &
(data['交易日期'] <= '2022-10-31')]
alt.Chart(data2022).mark_rect().encode(
alt.X('date(交易日期):O', title='day'),
alt.Y('month(交易日期):O', title='month'),
color='指数回报率:Q'
).properties(
title="2022年指数回报率热力图"
)
需要注意的是,这里在调用encode()传递参数时,对参数的类型进行了声明,并通过函数对时间变量进行了处理。其中,声明参数类型的语法结构为:”冒号+参数类型“,例如'指数回报率:Q'
表示的就是声明指数回报率这个变量为数值型。常用的声明有T:时间型、Q:数值型、N:分类型等。而处理时间变量的函数为:“时间单位(时间百变量)”,频度有year、month和date等。alt.Chart(data).mark_line().encode(
x='交易日期',
y='开盘指数'
)
month()
,将日期的频度变小为月度,同时使用mean()
函数求出对应的月度均值。alt.Chart(data).mark_line().encode(
x='month(交易日期):T',
y='mean(开盘指数):Q',
color='指数名称:N'
).properties(
title="指数回报率月度时序图"
)
color
参数指定图例的对象为指数的名称,并用:N
声明其为分类变量。alt.layer()
函数来实现:#多图合一
chart1=alt.Chart(data).mark_line().encode(
x='month(交易日期):T',
y='mean(开盘指数):Q',
color='指数名称:N'
)
chart2=alt.Chart(data).mark_line().encode(
x='month(交易日期):T',
y='mean(最高指数):Q',
color='指数名称:N'
)
chart3=alt.Chart(data).mark_line().encode(
x='month(交易日期):T',
y='mean(最低指数):Q',
color='指数名称:N'
)
chart4=alt.Chart(data).mark_line().encode(
x='month(交易日期):T',
y='mean(收盘指数):Q',
color='指数名称:N'
)
alt.layer(chart1,chart2,chart3,chart4)
alt.hconcat()
表示将图按水平方向排列,alt.vconcat()
表示按垂直方向排列。#同时绘制多图
#水平排列
chart1 = alt.Chart(data).mark_point().encode(
x='最低指数:Q',
y='最高指数:Q',
color='指数名称:N'
).properties(
height=300,
width=300
)
chart2 = alt.Chart(data).mark_bar().encode(
x='count()',
y=alt.Y('指数回报率:Q', bin=alt.Bin(maxbins=30)),
color='指数名称:N'
).properties(
height=300,
width=100
)
plot1=alt.hconcat(chart1, chart2)
#使用chart1 | chart2效果相同
#垂直排列
brush = alt.selection(type='interval', encodings=['x'])
base = alt.Chart(data).mark_area().encode(
x = '交易日期:T',
y = '收盘指数:Q'
).properties(
width=600,
height=200
)
upper = base.encode(
alt.X('交易日期:T', scale=alt.Scale(domain=brush))
)
lower = base.properties(
height=60
).add_selection(brush)
plot2=alt.vconcat(upper, lower)
encode()
函数中添加column()
来指定拆分的对象,进而画出分面图。#分面图
alt.Chart(data).mark_line().encode(
x = '交易日期:T',
y = '收盘指数:Q',
color= '指数名称:N',
column='指数名称:N'
).properties(
width=180,
height=180
)
interactive()
选项,使得图形可以通过滑动鼠标滚轮进行放缩,同时在encode()
中添加tooltip
来声明需要展示的标签,实现将鼠标移到某一点上时,展示该点对应的标签信息。下面展示交互式散点图的画法。#交互式散点图
alt.Chart(data).mark_point(size=60).encode(
x='month(交易日期):T',
y='mean(收盘指数):Q',
color='指数名称:N',
tooltip=['指数名称', '交易日期', '开盘指数', '最高指数', '最低指数', '收盘指数', '指数回报率']
).interactive()
selection
和condition
,selection
是一种选择器,可以理解为根据不同的情况做出不同的反应,selection
必须被添加在图上才可以使用,其中做出的反应由condition
确定,某些属性的值可以根据不同的condition
做出不同的响应。我们在上一张散点图的基础上添加selection
功能,首先使用selection_interval()
函数创建一个间隔选择:brush = alt.selection_interval() # 创建一个选区
add_selection()
将此画笔绑定到我们的图表:alt.Chart(data).mark_point(size=60).encode(
x='month(交易日期):T',
y='mean(收盘指数):Q',
color='指数名称:N'
).add_selection(
brush
)
condition()
来对由selection()
生成的选区进行操作。比如创建条件颜色编码:我们将颜色绑定到所选内容中点的列,并将非选择区域中的点设置为灰色。alt.Chart(data).mark_point(size=60).encode(
x='month(交易日期):T',
y='mean(收盘指数):Q',
color=alt.condition(brush, '指数名称:N', alt.value('lightgray'))
).add_selection(
brush
)
save()
函数设置保存路径,并将后缀设置为.html,就可以在网页中打开交互式图像,比如对上图的命令稍加修改:condition=alt.Chart(data).mark_point(size=60).encode(
x='month(交易日期):T',
y='mean(收盘指数):Q',
color=alt.condition(brush, '指数名称:N', alt.value('lightgray'))
).add_selection(
brush
)
condition.save('D:\Altair\condition.html')
本文介绍了Altair库强大的绘图功能,与常用的可视化库不同,Altair还提供了丰富的交互式图像设计功能。这里所介绍的只是基础的语法结构,如果还想画出更多高级精美的交互式可视化图,欢迎读者自行探索,后续我们也将推出更多数据可视化教程,敬请期待!
最后,我们为大家揭秘雪球网(https://xueqiu.com/)最新所展示的沪深证券和港股关注人数增长Top10。
对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
关于我们
微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
武汉字符串数据科技有限公司一直为广大用户提供数据采集和分析的服务工作,如果您有这方面的需求,请发邮件到statatraining@163.com,或者直接联系我们的数据中台总工程司海涛先生,电话:18203668525,wechat: super4ht。海涛先生曾长期在香港大学从事研究工作,现为知名985大学的博士生,爬虫俱乐部网络爬虫技术和正则表达式的课程负责人。
此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。
投稿邮箱:statatraining@163.com投稿要求:1)必须原创,禁止抄袭;2)必须准确,详细,有例子,有截图;注意事项:1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。