Python 中可用的绘图库提供了多种呈现数据的方式,您可以根据自己的偏好选择灵活性、设计、易用性或特定风格。
Altair 中的绘图提供了与其他库不同的解决方案,我发现这种方案更简单,因为绘图量是可扩展的。它具有优雅的界面,这要归功于 Vega,这是一种声明式绘图语言,它允许您定义绘图的外观,而不是编写循环和条件语句来构建它们。
精通绘图
我通过绘制相同的多条形图来比较每个 Python 绘图库。在我们进一步深入之前,请注意您可能需要调整您的 Python 环境以运行此代码,包括以下内容。
数据可在线获取,可以使用 pandas 导入
import pandas as pd
df = pd.read_csv('https://anvil.works/blog/img/plotting-in-python/uk-election-results.csv')
现在我们准备好了。作为比较,这是我们在 Matplotlib 中制作的图表

英国选举结果的 Matplotlib 图表(© 2020 Anvil)
Matplotlib 图表用了 16 行代码来创建,包括手动计算每个条形的位置。
以下是如何在 Altair 中制作类似图表的方法
import altair as alt
chart = alt.Chart(df).mark_bar().encode(
x='party',
y='seats',
column='year',
color='party',
)
chart.save('altair-elections.html')
更加简洁!就像 Seaborn 一样,Altair 可以处理每列一个变量的数据(长格式)。这允许您将每个变量映射到图表的某个方面——Altair 将这些方面称为“通道”。在我们的例子中,我们希望 x 轴上每个 party
有一个条形,y 轴上是每个政党赢得的 seats
,并且我们希望按 year
将条形分组到 column
中。我们还希望按 party
对条形进行 color
着色。这就是您在文字中描述它的方式,而且这正是代码所说的!
这是图表的样子

具有默认样式的 Altair 图表(© 2020 Anvil)
调整样式
这与我们想要的相差不远。与 Matplotlib 图表的主要区别在于,每个 Altair year
组之间都显示了一些空白——这只是 Altair 多条形图的一个特性,而不是问题。
但是,我们确实希望进行一些其他的细微样式改进。
非整数值
两个非整数年份名称(Feb 1974
和 Oct 1974
)显示为 NaN
。我们可以通过将 year
值转换为字符串来修复这些问题
df['year'] = df['year'].astype(str)
指定排序顺序
然后我们还需要告诉 Altair 如何对数据进行排序。Altair 允许我们通过传递 Column
对象来指定有关 column
通道的更多详细信息。因此,我们告诉它按照数据在 DataFrame 中出现的顺序进行排序
chart = alt.Chart(df).mark_bar().encode(
# ...
column=alt.Column('year', sort=list(df['year']), title=None),
# ...
)
删除轴标题
我们通过设置 title=None
从图表顶部删除了“year”标签。我们还要从每列中删除“party”标签
chart = alt.Chart(df).mark_bar().encode(
x=alt.X('party', title=None),
# ...
)
指定颜色映射
最后,我们希望指定我们自己的颜色用于条形。Altair 允许我们指定 domain
中的值和 range
中的颜色之间的映射,这正是我们需要的
cmap = {
'Conservative': '#0343df',
'Labour': '#e50000',
'Liberal': '#ffff14',
'Others': '#929591',
}
chart = alt.Chart(df).mark_bar().encode(
# ...
color=alt.Color('party', scale=alt.Scale(domain=list(cmap.keys()), range=list(cmap.values())))
)
带有样式调整的最终代码
应用这些样式调整后,我们的代码在视觉上略微逊色,但它仍然使用了使 Altair 如此可扩展的声明式方法。我们仍然将来自数据的独立变量分配给绘图的不同方面,而不是像我们在 Matplotlib 中经常需要做的那样执行复杂的数据操作。唯一的区别是我们的变量名现在被包装在诸如 alt.X()
之类的对象中,这些对象允许我们调整它们的外观
import altair as alt
from votes import long as df
cmap = {
'Conservative': '#0343df',
'Labour': '#e50000',
'Liberal': '#ffff14',
'Others': '#929591',
}
df['year'] = df['year'].astype(str)
# We're still assigning, e.g. 'party' to x, but now we've wrapped it
# in alt.X in order to specify its styling
chart = alt.Chart(df).mark_bar().encode(
x=alt.X('party', title=None),
y='seats',
column=alt.Column('year', sort=list(df['year']), title=None),
color=alt.Color('party', scale=alt.Scale(domain=list(cmap.keys()), range=list(cmap.values())))
)
chart.save('altair-elections.html')
公平地说,我们现在已经达到了与我们在 Matplotlib 中使用的代码行数相同的数量 (16)!
这是应用了我们的样式调整的 Altair 图表

具有自定义样式的 Altair 图表(© 2020 Anvil)
结论
虽然使用 Altair 绘图所需的代码量与其他库类似,但其声明式绘图语言增加了一层我逐渐欣赏的复杂性。Altair 还提供了一种干净地分离的方式来调整和修改样式,这使得语法远离用于绘图的代码块。当考虑 Python 的绘图解决方案时,Altair 是另一个很棒的库。您可以在 Anvil 上交互式运行此代码(需要帐户)或使用 此开源运行时在本地运行。
---
本文基于 Anvil 博客上的 P在 Altair 中绘图,并已获得许可重复使用。
评论已关闭。