改进具有多行的交互式 Altair 折线图的选项
Options for improving interactive Altair line charts with many rows
我的要求是绘制形状为 (50,000, 2) 的 pandas 数据框作为 交互式折线图 。一列包含 datetime64[ns]
,另一列包含浮点整数。
不幸的是,对于如此多的数据,交互式图表在 平移和缩放 方面变得相当慢。我的图表非常基础,我可以观察到一旦我将行数减少到 < ~10,000,性能就会明显好转。我已阅读 FAQ 并了解官方指南甚至不建议开始时超过 5,000 行。尽管如此,我正在寻找提高性能的方法,而且似乎没有太多关于这个的讨论
我不需要一次显示所有 50,000 个数据点,但我确实希望将所有 50,000 个数据点存储在一个独立的 .html 文件(即图表)中。
我正在考虑“将绘图保存到磁盘”、“使用滑块创建滑动 window 效果来限制一次显示的数据点数量,”使用更多高效的数据类型”,“改变线条的外观以减少渲染强度”。真的,任何可能有帮助的东西都很好。在某些情况下,我正在将性能与更专用的可视化软件(如 Matlab)进行比较,我在其中用这么多数据制作交互式折线图没问题。
或者,我也很高兴听到解释,为什么由于 HTML、JSON、Altair、Vega 或其他方面的限制,无法交互式绘制如此多的数据否则。
正在努力提高 Vega 的性能(包括通过 WebGL),您可以在此处阅读 https://github.com/vega/vega/issues/2619。在那些土地之前,我认为你最好的选择是放大到一个较小的区域,这听起来很有效,因为你提到不需要一次显示所有点。我发现使用 data_server 后端也可以帮助解决一些大数据减慢问题,尽管与渲染无关。
import pandas as pd
import numpy as np
import altair as alt
alt.data_transformers.enable('data_server')
N=50000
test_df = pd.DataFrame({'t' : range(0, N, 1),
'A' : np.random.randint(0, 100, size=N)})
alt.Chart(test_df).mark_point().encode(
alt.X('t', scale=alt.Scale(domain=[4000, 6000])),
alt.Y('A', scale=alt.Scale(domain=[40, 60]))).interactive()
我的要求是绘制形状为 (50,000, 2) 的 pandas 数据框作为 交互式折线图 。一列包含 datetime64[ns]
,另一列包含浮点整数。
不幸的是,对于如此多的数据,交互式图表在 平移和缩放 方面变得相当慢。我的图表非常基础,我可以观察到一旦我将行数减少到 < ~10,000,性能就会明显好转。我已阅读 FAQ 并了解官方指南甚至不建议开始时超过 5,000 行。尽管如此,我正在寻找提高性能的方法,而且似乎没有太多关于这个的讨论
我不需要一次显示所有 50,000 个数据点,但我确实希望将所有 50,000 个数据点存储在一个独立的 .html 文件(即图表)中。
我正在考虑“将绘图保存到磁盘”、“使用滑块创建滑动 window 效果来限制一次显示的数据点数量,”使用更多高效的数据类型”,“改变线条的外观以减少渲染强度”。真的,任何可能有帮助的东西都很好。在某些情况下,我正在将性能与更专用的可视化软件(如 Matlab)进行比较,我在其中用这么多数据制作交互式折线图没问题。
或者,我也很高兴听到解释,为什么由于 HTML、JSON、Altair、Vega 或其他方面的限制,无法交互式绘制如此多的数据否则。
正在努力提高 Vega 的性能(包括通过 WebGL),您可以在此处阅读 https://github.com/vega/vega/issues/2619。在那些土地之前,我认为你最好的选择是放大到一个较小的区域,这听起来很有效,因为你提到不需要一次显示所有点。我发现使用 data_server 后端也可以帮助解决一些大数据减慢问题,尽管与渲染无关。
import pandas as pd
import numpy as np
import altair as alt
alt.data_transformers.enable('data_server')
N=50000
test_df = pd.DataFrame({'t' : range(0, N, 1),
'A' : np.random.randint(0, 100, size=N)})
alt.Chart(test_df).mark_point().encode(
alt.X('t', scale=alt.Scale(domain=[4000, 6000])),
alt.Y('A', scale=alt.Scale(domain=[40, 60]))).interactive()