从Plotly v5.15.0开始,Plotly有对Polars的本地支持。因此,您可以将DataFrame作为第一个参数传递,并将列名称作为字符串传递给x和y编码参数。这是一个很大的改进,因为它意味着我们可以使用Plotly API,而不需要首先转换为Pandas。
在本文中,我将展示一种在Matplotlib中制作具有不同颜色的图表的策略,并比较我们如何使用Plotly来制作这个图表。
我使用Matplotlib有着相当长的历史。然而,偶然的机会,我发现了Altair可视化库。经过几周的实验后,我停止使用Matplotlib,因为Altair似乎能以更少的努力制作出更漂亮的图表。最近,我一直在使用Plotly,并发现它与Altair有类似的优点。
注意:我不再是Matplotlib的常规用户,因此可能存在更好的方法来完成某些事情。然而,我采用的这些方法来自官方文档。
带有颜色组的散点图
在这个例子中,我们将制作一个关于泰坦尼克号数据集的散点图。散点图的x轴表示乘客的(对数)年龄,y轴表示乘客支付的(对数)票价。我们将根据乘客乘坐的舱位等级对点进行着色。我们更一般地将不同的乘客舱位等级称为组。
Matplotlib
我们首先使用Matplotlib来完成这个任务。在Matplotlib中,主要的挑战在于我们必须:
- 为不同的组传递一个颜色列表
- 遍历各个组,分别为每个组添加数据和标签
我们使用partition_by方法来遍历各个组。当我们传递as_dict=True参数时,我们得到一个字典,该字典将组键(即乘客等级)映射到组的DataFrame。这意味着我们既可以使用组键作为图例中的标签,又可以获得数据。我们使用标准的Python方式,通过.items方法遍历这个字典。
import polars as pl
import matplotlib.pyplot as plt
df = pl.read_csv("titanic.csv")
fig, ax = plt.subplots(figsize=(6,6))
# 三种乘客等级的颜色列表
colours = ['tab:blue', 'tab:red','tab:green']
# 遍历组键并使用partition_by对DataFrame进行分组
for idx,(passenger_class,passenger_class_df) in enumerate(
df.partition_by("Pclass",as_dict=True).items()
):
# 获取该组的颜色
color = colours[idx]
# 将这组数据添加到轴上
ax.scatter(
x=passenger_class_df["Age"].log(),
y=passenger_class_df["Fare"].log(),
c=color,
label=passenger_class,
)
# 添加元数据
ax.legend()
ax.grid(True)
ax.title.set_text("Log Age vs Log Fare by Passenger class")
ax.set_xlabel("Log Age")
ax.set_ylabel("Log Fare")
plt.show()
使用df.partition_by的这种策略也适用于其他Matplotlib图表类型,如多色时间序列图表。
总的来说,实现遍历各个组的循环感觉像是很多工作。我还发现,用于添加元数据的方法名称并不直观——例如,我们使用 ax.title.set_text 来设置标题,但使用 ax.set_xlabel 来设置X轴标签。
Plotly
现在我们使用 Plotly(通过 Plotly Express API)来创建这个相同的图表。使用 Plotly,我们只需将颜色列传递给它,而无需遍历各个组。我们还可以将轴标签和标题作为参数传递给散点图函数。
需要注意的一点是,我们需要将颜色Pclass列转换为字符串数据类型(pl.Utf8),以便 Plotly 知道这些数据是分类数据而不是数值数据。
import plotly.express as px
px.scatter(
x=df["Age"].log(),
y=df["Fare"].log(),
# 将Pclass转换为字符串
color=df["Pclass"].cast(pl.Utf8),
labels = {
"x":"Log Age",
"y":"Log Fare",
"color":"Survived"
},
title="Log Age vs Log Fare by Passenger class",
height=600
)
我认为使用 Plotly 确实方便多了。Plotly 的其他优势在于::
- 该API在不同类型的图表之间相对一致
- 在 Jupyter 中,图表默认具有交互式提示框(tooltips)
结论
是一个强大的绘图工具。然而,如果你只需要标准的图表类型,那么它可能超出了你的需求。当我制作这类图表时,我使用 Plotly 或 Altair。Altair 需要 Pandas DataFrame 作为输入,但我在 Polars 中完成所有操作,然后在将数据传递给图表时调用 df.to_pandas()。
我认为Matplotlib的主要用途是当你需要对画布进行精细控制时。例如,如果你需要在科学论文中安排多个非标准图表。否则,我会说像Plotly这样的工具通过减少管理图表细节的时间来增加你的数据分析速度。