VegaLite: facet plot with running average layer

I have a dataset with continuous values and would like to plot those values together with their running averages in a layered plot. Works well in this simple case:

using Random, DataFrames, Queryverse
Random.seed!(1234)
df = DataFrame(index=1:100, value=rand(100))

df |> @vlplot(transform=[{frame= [-15, 15], window=[{op=:mean, field=:value, as=:avg_value}]}]) +
@vlplot(
    mark={:line, strokeWidth=2, opacity=0.5},
    x="index:q",
    y="value:q"
) +
@vlplot(
    mark={:line, strokeWidth=3},
    x="index:q",
    y="avg_value:q"
)

image

However, if I now would like to stratify the plot according to a categorical variable, the following fails:

df[!, :category] .= rand(1:2, 100)

df |> @vlplot(facet={column={field="category", typ="nominal"}}) +
(
    @vlplot() +
    @vlplot(
        mark=:line,
        x="index:q",
        y="value:q",
    ) + @vlplot(
        mark={:line, strokeWidth=3},
        transform=[{frame= [-15, 15], window=[{op=:mean, field=:value, as=:avg_value}]}],
        x="index:q",
        y={field=:avg_value, typ=:quantitative, aggregate=:mean},
        color={value=:red}
    )
)

image […]
Putting the transform statement in other places (for instance the initial @vlplot()'s) unfortunately results in the same error. This simplified, transformation-less version however works:

df |> 
@vlplot(facet={column={field="category", typ="nominal"}}) +
(
    @vlplot() +
    @vlplot(
        mark=:line,
        x="index:q",
        y="value:q",
    ) + @vlplot(
        mark={:rule, strokeWidth=3},
        y={field=:value, typ=:quantitative, aggregate=:mean},
        color={value=:red}
    )
)

image

Any idea what I’m doing wrong?

It’s not that you are are doing it wrong, or at least, I can’t tell where it is done wrong.

I needed some time with trial and error to develop the following suggestion based on your code:

df |>
@vlplot(
    transform=[{
        frame= [-15, 15], 
        window=[{op=:mean, field=:value, as=:avg_value}],
        groupby=["category"]
    }],
    facet={column={field="category", type="nominal"}}
) +
(
    @vlplot() +
    @vlplot(
        mark=:line,
        x="index:q",
        y="value:q"
    ) +
    @vlplot(
        mark={:line, strokeWidth=3},
        x="index:q",
        y={field=:avg_value, type="quantitative", aggregate=:mean},
        color={value=:red}
    )
)

I didn’t check if the calculated mean values (red line) are correct!
facet

1 Like

Thanks a lot, works like a charm! I thought I had tried putting the transform there before, but apparently not :). Out of curiosity, does the groupby ensure that the transformation window is only applied per group?

I hope that. That is what I meant with “i didn’t check the mean values”.
Thats how I interprete:

groupby String [ ] The data fields for partitioning the data objects into separate windows. If
unspecified, all data points will be in a single window.

from here

1 Like