首页 > 解决方案 > 在 Altair 中绘制指示分组堆叠条形图净值的标记

问题描述

我在这里有一个分组的堆积条形图,Python 使用 Altair 包,具有​​正值和负值。如何绘制标记以指示每个条的净值?这里的情节使用红线标记,但菱形或点会很好。

df1=pd.DataFrame(10*np.random.rand(4,3),index=["A","B","C","D"],columns=["I","J","K"])
print(df1)
df2=pd.DataFrame(-10*np.random.rand(4,3),index=["A","B","C","D"],columns=["I","J","K"])
df3=pd.DataFrame(10*np.random.rand(4,3),index=["A","B","C","D"],columns=["I","J","K"])

def prep_df(df, name):
    df = df.stack().reset_index()
    df.columns = ['c1', 'c2', 'values']
    df['DF'] = name
    return df

df1 = prep_df(df1, 'DF1')
df2 = prep_df(df2, 'DF2')
df3 = prep_df(df3, 'DF3')

df = pd.concat([df1, df2, df3])

alt.Chart(df).mark_bar().encode(

    # tell Altair which field to group columns on
    x=alt.X('c2:N', title=None),

    # tell Altair which field to use as Y values and how to calculate
    y=alt.Y('sum(values):Q',
        axis=alt.Axis(
            grid=False,
            title=None)),

    # tell Altair which field to use to use as the set of columns to be  represented in each group
    column=alt.Column('c1:N', title=None),

    # tell Altair which field to use for color segmentation
    color=alt.Color('DF:N',
            scale=alt.Scale(
                # make it look pretty with an enjoyable color pallet
                range=['#96ceb4', '#ffcc5c','#ff6f69'],
            ),
        ))\
    .configure_view(
        # remove grid lines around column clusters
        strokeOpacity=0
    )

我尝试在单独的 df 中计算“Net”,然后执行以下操作:

tick = alt.Chart(source).mark_tick(
    color='red',
    thickness=2,
    size=40 * 0.9,  # controls width of tick.
).encode(
    x=alt.X('c2:N', title=None),
    y=alt.Y('Net')
)

但错误是:未定义“网络”

标签: altair

解决方案


无需预先计算总和;altair 可以直接做到这一点。这里的诀窍是分面图表不能分层,因此您必须改为分面分层图表:

base = alt.Chart(df).encode(
    x=alt.X('c2:N', title=None),
    y=alt.Y('sum(values):Q',
        axis=alt.Axis(
            grid=False,
            title=None)),
)

bars = base.mark_bar().encode(
    color=alt.Color('DF:N',
            scale=alt.Scale(
                range=['#96ceb4', '#ffcc5c','#ff6f69'],
            ),
        )
)

net = base.mark_tick(
    color='red',
    thickness=2,
    size=18,
)

alt.layer(bars, net).facet(
    column=alt.Column('c1:N', title=None)
).configure_view(
    strokeOpacity=0
)

在此处输入图像描述


推荐阅读