【问题标题】:Altair combining multiple data setsAltair 组合多个数据集
【发布时间】:2018-09-14 08:04:23
【问题描述】:

我最近才发现 Vega/Vega-Lite 和 Altair,并将其视为最佳 Python 绘图工具的真正竞争者。

我目前正在努力解决的问题是将来自两个数据帧的信息绘制到共享一个或两个轴的同一个图表中。

我试过这样的事情:

plot1 = alt.Chart(df1).mark_point().encode(x = 'time:T', y = [...])[...]
plot2 = alt.Chart(df2).mark_point().encode(x = 'time:T', y = [...])[...]

这行得通,但它很笨重而且不是很好。

我遇到了 LayerChart 对象,但从文档中我不太清楚如何正确使用它来绘制多个数据集。

  • 有人有这种图表的例子吗?
  • 我需要做什么才能获得双 y 轴?

【问题讨论】:

  • df1 和 df2 的一些小数据将使您的问题完整,并允许对您的问题进行试验
  • 这是 Altair 库中分层图表的示例:altair-viz.github.io/gallery/…,这是 Altair 的 LayerChart documentation。如果您对分层有任何更具体的问题,请随时提问!
  • 非常感谢您。我本来想添加更多数据,但由于这是一个工作项目,所以这是一个很大的禁忌。
  • 但是以时间序列为例,您还希望将注释绘制到存储在单独数据框中的特定点。我确实阅读了示例和文档,这很有帮助。但是在图库中,我没有看到使用两个数据集的示例,只有来自同一数据集的不同属性。现在在 alt.LayerChart 接口的文档中有关键字 datasets。我不确定我会如何使用它。
  • 嗨@AJK——你不必提供专有数据,但如果你能更具体地说明你想做的事情,你通常会在 StackOverflow 上得到更有用的答案。这可能涉及创建一些小数据集来说明您要解决的问题。阅读stackoverflow.com/help/mcve的提示

标签: python visualization vega-lite altair


【解决方案1】:

通过在函数中分离图表逻辑来制作 DRYer 代码,然后进行迭代。

给定

import pandas as pd
import altair as alt


df0 = pd.DataFrame(dict(times=[1, 2, 3], values=[2, 2, 7]))
df1 = pd.DataFrame(dict(times=[2, 3, 5], values=[3, 9, 8]))
df2 = pd.DataFrame(dict(times=[3, 6, 8], values=[2, 6, 7]))
df3 = pd.DataFrame(dict(times=[6, 7, 9], values=[3, 2, 5]))

代码

def base_chart(df):
    """Return an Altair chart."""
    # Add lengthy chart arguments here
    base = alt.Chart(
        df,
        width=500,
        height=300,
    ).mark_line(
    ).encode(
        x="times", 
        y="values"
    )
    return base


def layer_charts(dfs, chart_func):
    """Return a layered chart."""

    return alt.layer(*[chart_func(df) for df in dfs])

演示

layer_charts([df0, df1, df2, df3], base_chart)

【讨论】:

  • 在挠头一小时后找到了这个答案——谢谢。我不认为您知道在 altair 绘图上绘制简单直线的另一种方法?这很实用,但对于 500 条水平线来说很慢,这在 Bokeh 中很快。
【解决方案2】:

具有不同数据集的图表可以与Altair documentation 中描述的任何机制分层在一起。

例如:

import pandas as pd
import altair as alt

df1 = pd.DataFrame({
    'times': [1, 2, 3],
    'values': [1, 5, 4],
})

df2 = pd.DataFrame({
    'times': [2, 3, 4],
    'values': [4, 2, 3],
})

chart1 = alt.Chart(df1).mark_line().encode(x='times', y='values')
chart2 = alt.Chart(df2).mark_line().encode(x='times', y='values')

chart1 + chart2

【讨论】:

  • 非常感谢您!您能否详细说明 LayerChart 控件中的 datasets 关键字是什么?
  • 所有顶级图表对象都接受datasets 属性,该属性是名称到数据集的键值映射,可以在该图表及其任何子项中使用NamedData 类进行引用。但它更像是一项高级功能——我不建议在 99% 的情况下直接使用它。
  • 谢谢,这正是我所关心的。所以我可以传递类似 {'data1':dataset1, 'data2':dataset2} 的东西。在随后的图层图表中,我将能够使用诸如 alt.Chart(data1).mark_bar().encode([...]) 之类的符号?再次感谢您的帮助,非常感谢。是否有关于创建动态更新 altair Charts 的文档?我当前使用 ipywidgets 的解决方案有效,但在任何更新时我都会重建整个图表。在 Bokeh 中,数据源是抽象的,因此无需重建图形即可操作数据。
  • 抱歉,StackOverflow 回答 cmets 不是提出和回答多个详细问题的好地方。我建议使用 altair google group 或 vega slack 频道。
猜你喜欢
  • 2022-11-11
  • 1970-01-01
  • 2020-02-13
  • 2019-01-10
  • 2020-05-13
  • 1970-01-01
  • 2023-04-02
  • 2017-11-03
相关资源
最近更新 更多