Shared axis between rows but not columns

45 views Asked by At

enter image description here

I have this error bars grouped by rows/columns. The 'Y' label is the same across all of them, but the scale can be very different. I need to have the same y-axis scale between rows ([0, 2.5] for the first row, [0, 0.25] for the second), and only the first plot of each row should show y-label and ticks.

If I use resolve_scale(y='independent') then the y-axis is independent across rows and columns (and I don't want that), and y-label and ticks appear in all plots, like this

enter image description here

import numpy as np
import pandas as pd
import altair as alt

np.random.seed(0)
    
model_keys = ['M1', 'M2']
scene_keys = ['S1', 'S2']
layer_keys = ['L1', 'L2']

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

for sc in scene_keys:
    for m in model_keys:
        for l in layer_keys:
            for s in range(10):
                y = np.random.rand(10) / 10
                if m == 'M1':
                    y *= 10
                if l == 'L1':
                    y *= 5
                data_y = list(y)
                ys += data_y
                scenes += [sc] * len(data_y)
                models += [m] * len(data_y)
                layers += [l] * len(data_y)

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

bars = alt.Chart(df, width=100, height=90).mark_bar().encode(
    x=alt.X('Scenes:N',
        title=None,
        axis=alt.Axis(
            grid=False,
            title=None,
            labels=False,
        ),
    ),
    y=alt.Y('Y:Q',
        aggregate='mean',
        axis=alt.Axis(
            grid=True,
            title='Y',
            titleFontWeight='normal',
        ),
    ),
)

bars = bars.facet(
    row=alt.Row('Model:N',
        title=None,
    ),
    column=alt.Column('Layer:N',
        title=None,
    ),
    spacing={"row": 10, "column": 10},
)

# bars = bars.resolve_scale(y='independent')

bars.save('test.html')

One dirty fix would be to split the field 'Y' into 'M1 Y' and 'M2 Y', create two chars and concatenate them, but this is not practical if there are many rows.

0

There are 0 answers