拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 带有Altair的多个分组图表

带有Altair的多个分组图表

白鹭 - 2022-01-23 2252 0 0

带有 Altair 的多个分组图表

我的资料有 4 个属性:资料集 (D1/D2)、模型 (M1/M2)、层 (L1/L2)、场景 (S1/S2)。我可以制作按场景分组的图表,然后水平和垂直合并图(上图)。但是,我希望按场景和资料集进行“双重分组”,例如通过放置彼此相邻但具有不同不透明度或图案/影线的蓝色/橙色条来合并 D1 和 D2 绘图。

基本上是这样的(假设黑色特征是阴影图案)。

带有 Altair 的多个分组图表

这是重现第一个情节的代码

import numpy as np
import itertools
import argparse
import pandas as pd
import matplotlib.pyplot as plt
import os
import altair as alt
alt.renderers.enable('altair_viewer')

np.random.seed(0)

################################################################################

model_keys = ['M1', 'M2']
data_keys = ['D1', 'D2']
scene_keys = ['S1', 'S2']
layer_keys = ['L1', 'L2']

ys = []
models = []
dataset = []
layers = []
scenes = []

for sc in scene_keys:
    for m in model_keys:
        for d in data_keys:
            for l in layer_keys:
                for s in range(10):
                    data_y = list(np.random.rand(10) / 10)
                    ys  = data_y
                    scenes  = [sc] * len(data_y)
                    models  = [m] * len(data_y)
                    dataset  = [d] * len(data_y)
                    layers  = [l] * len(data_y)


# ------------------------------------------------------------------------------


df = pd.DataFrame({'Y': ys,
                   'Model': models,
                   'Dataset': dataset,
                   'Layer': layers,
                   'Scenes': scenes})

bars = alt.Chart(df, width=100, height=90).mark_bar().encode(
    # field to group columns on
    x=alt.X('Scenes:N',
        title=None,
        axis=alt.Axis(
            grid=False,
            title=None,
            labels=False,
        ),
    ),
    # field to use as Y values and how to calculate
    y=alt.Y('Y:Q',
        aggregate='mean',
        axis=alt.Axis(
            grid=True,
            title='Y',
            titleFontWeight='normal',
        ),
    ),
    # field to use for sorting
    order=alt.Order('Scenes',
        sort='ascending',
    ),
    # field to use for color segmentation
    color=alt.Color('Scenes',
        legend=alt.Legend(orient='bottom',
            padding=-10,
        ),
        title=None,
    ),
)

error_bars = alt.Chart(df).mark_errorbar(extent='ci').encode(
    x=alt.X('Scenes:N'),
    y=alt.Y('Y:Q'),
)

text = alt.Chart(df).mark_text(align='center',
    baseline='line-bottom',
    color='black',
    dy=-5 # y-shift
).encode(
    x=alt.X('Scenes:N'),
    y=alt.Y('mean(Y):Q'),
    text=alt.Text('mean(Y):Q', format='.1f'),
)

chart_base = bars   error_bars   text

chart_base = chart_base.facet(
    # field to use to use as the set of columns to be represented in each group
    column=alt.Column('Layer:N',
        # header=alt.Header(
            # labelFontStyle='bold',
        # ),
        title=None,
        sort=list(set(models)), # get unique indices
    ),
    spacing={"row": 0, "column": 15},
)

def unique(sequence):
    seen = set()
    return [x for x in sequence if not (x in seen or seen.add(x))]

for i, m in enumerate(unique(models)):
    chart_imnet = chart_base.transform_filter(
        alt.FieldEqualPredicate(field='Dataset', equal='D1'),
    ).transform_filter(
        alt.FieldEqualPredicate(field='Model', equal=m)
    )
    chart_places = chart_base.transform_filter(
        alt.FieldEqualPredicate(field='Dataset', equal='D2')
    ).transform_filter(
        alt.FieldEqualPredicate(field='Model', equal=m)
    )

    if i == 0:
        title_params = dict({'align': 'center', 'anchor': 'middle', 'dy': -10})
        chart_imnet = chart_imnet.properties(title=alt.TitleParams('D1', **title_params))
        chart_places = chart_places.properties(title=alt.TitleParams('D2', **title_params))

    chart_places = alt.concat(chart_places,
        title=alt.TitleParams(
            m,
            baseline='middle',
            orient='right',
            anchor='middle',
            angle=90,
            # dy=10,
            dx=30 if i == 0 else 0,
        ),
    )

    if i == 0:
        chart = (chart_imnet | chart_places).resolve_scale(x='shared')
    else:
        chart = (chart & (chart_imnet | chart_places).resolve_scale(x='shared'))

chart.save('test.html')

uj5u.com热心网友回复:

目前,我不知道一个好的答案,但是一旦带有 Altair 的多个分组图表

请参阅带有 Altair 的多个分组图表

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *