绘图标记,指示Altair中分组的堆叠条形图的净值

时间:2020-04-28 02:06:47

标签: altair

我有一个分组的堆积条形图here,使用Altair软件包的Python,带有正值和负值。如何绘制标记以指示每个条的净值?情节here使用红线标记,但是菱形或一点就可以了。

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')
)

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

1 个答案:

答案 0 :(得分:1)

无需预先计算总和; 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
)

enter image description here