altair icon indicating copy to clipboard operation
altair copied to clipboard

Python expressions cannot be used where the entire expression is an array

Open joelostblom opened this issue 1 year ago • 3 comments

What is your suggestion?

In the code below, we combine columns into an array by passing them as a list inside the JS expression string. This is not possible to replicate with a python expression using alt.datum since transform calculate will not accept a list (and neither will alt.expr). This is another case (in addition to https://github.com/vega/altair/issues/3366 where the python expression don't cover everything the JS expressions can do), and it would be great if we could somehow support using python expressions for this too (maybe we need alt.expr.array(...) or similar?).

import pandas as pd
import altair as alt

mpg = pd.read_csv('https://raw.githubusercontent.com/has2k1/plotnine/4159f9548fa5f95c02366efc324e88f9ba79af09/plotnine/data/mpg.csv')

alt.Chart(mpg, width=100, height=100).mark_point().transform_calculate(
    man_model_drv='[datum.manufacturer, datum.model, datum.drv]'
    # Does not work
    # man_model_drv=[alt.datum.manufacturer, alt.datum.model, alt.datum.drv]
).encode(
    x='cty',
    y='hwy',
).facet(
    'man_model_drv:N',
    columns=7
)

ref https://github.com/vega/altair/discussions/3601#discussioncomment-10698263

Have you considered any alternative solutions?

No response

joelostblom avatar Sep 21 '24 05:09 joelostblom

merge seems to be the closest in terms of signature, but this accepts object - not sure if that works?

Otherwise I think we'd need vega to implement a toArray type coercion function like:

toArray(value1[, value2, ...])

dangotbanned avatar Sep 21 '24 10:09 dangotbanned

Good idea to try merge, but unfortunately it doesn't work:

image

It did, however, give me the idea to try out slice and that does in fact work.

man_model_drv=alt.expr.slice([alt.datum.manufacturer, alt.datum.model, alt.datum.drv])

While it is not the most intuitive, it is at least convenient to type out. Not sure if it is still worthwhile creating toArray in VL, or just using slice when it is needed. Another option would be to just create expr.array(...) in altair as an alias for expr.slice(..., 0).

joelostblom avatar Sep 21 '24 13:09 joelostblom

Good idea to try merge, but unfortunately it doesn't work:

image

It did, however, give me the idea to try out slice and that does in fact work.

man_model_drv=alt.expr.slice([alt.datum.manufacturer, alt.datum.model, alt.datum.drv])

Interesting 🤔

I've been reading the docs for these a lot in #3600 and that was not what I expected would happen - but great that it works

dangotbanned avatar Sep 21 '24 14:09 dangotbanned