Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support using param / expr with field keys to control which data column is used for an encoding #7365

Open
joelostblom opened this issue Apr 8, 2021 · 17 comments
Labels

Comments

@joelostblom
Copy link
Contributor

I suspect there might be an open issue for this somewhere but I could not find it when searching. The new parameter feature looks very cool, but I can't find and example of param / expr used together with the field key and when I try it in the vega editor, it says it only supports strings as values for this field. Would it be possible to add this functionality so that a field value could be set dynamically, e.g. to change which column is plotted on the x and y axis via a dropdown? Or am I not understanding how parameters are supposed to work?

A workaround for this is mention in #7264 by first folding and then filtering on a param / expr, but it would be need if this feature was directly supported. To be clear a use case would be to create something like this (minus the cluster count calculations):

image

@domoritz
Copy link
Member

domoritz commented Apr 8, 2021

I don't see why it wouldn't work but it may not be easy to add. The way to find out is to change the types for field and then seeing what breaks.

@domoritz domoritz added the P3 Should be fixed at some point label Apr 8, 2021
@joelostblom
Copy link
Contributor Author

joelostblom commented Apr 9, 2021

Oh cool! Just to clarify, with "change the types for field" does that mean to modify the VegaLite source to accept key-value pairs and not just strings as values for the field keys? Or is it something I can play around with in the online chart editor somehow?

I am thinking the syntax would look something like this Open the Chart in the Vega Editor:

{
  "data": {"url": "data/cars.json"},
  "params": [
    {
      "name": "sel",
      "select": {"type": "point"},
      "bind": {"input": "select", "options": ["Horsepower", "Acceleration"]}
    }
  ],
  "mark": "circle",
  "encoding": {
    "x": {"field": {"param": "sel"}, "type": "quantitative"},
    "y": {"field": "Miles_per_Gallon", "type": "quantitative"}
  }
}

Or maybe "x": {"field": {"expr": "sel_key"}, "type": "quantitative"}, I need to read up on the differences.

@domoritz
Copy link
Member

domoritz commented Apr 9, 2021

I was referring to the typescript sources. If you (or someone else) changes the types to support the param ref type (stricter than just a key value pair), you would see the downstream effects.

@kanitw kanitw added P4 Nice to Have and removed P3 Should be fixed at some point labels Oct 3, 2021
@kanitw
Copy link
Member

kanitw commented Oct 3, 2021

I think this will be super useful, but may require that all transforms and scales properties in Vega that take fields must take signals for the field names too, so this may require massive enhancement to Vega?

@ChristopherDavisUCI
Copy link
Contributor

Hi @kanitw, I was thinking about this feature and interested in trying to contribute. Do I understand your comment correctly that this can't be produced by changes on the Vega-Lite side, but would need to be done on the Vega side?

As an explicit example of what I want: I'd like for example this Repeated Line Chart but where, rather than showing all 3 views side-by-side, instead there is a dropdown menu that allows the user to select from among the 3 options.

Thanks for any suggestions!

Screen Shot 2022-03-03 at 8 39 58 AM

@domoritz
Copy link
Member

domoritz commented Mar 3, 2022

I think something like that could be. possible if you create a new dataset in Vega that has a field for y that is derived with an expression like data[fieldSignal]. Maybe this works in Vega-Lite already is you use param and calculate transform.

@ChristopherDavisUCI
Copy link
Contributor

Thank you, @domoritz, I will look into this!

@jwoLondon
Copy link
Contributor

I can confirm this works with the existing Vega-Lite implementation, although I am not sure if it is possible to customise the axis title to be data dependent. It would be useful if axis title could accept an expression in addition to a text literal.

Vega-Lite editor

{
  "data": {
    "url": "data/weather.csv"
  },
    "params": [
    {
      "name": "measure",
      "value": "temp_max",
      "bind": {
        "input": "select",
        "options": ["temp_max","precipitation","wind"]
      }
    }
  ],
  "transform": [
    {
      "calculate": "datum[measure]",
      "as": "y"
    }
  ],
  
    "mark": "line",
    "encoding": {
      "x": {"field": "date", "timeUnit": "month"},
      "y": {
        "field": "y",
        "aggregate": "mean"
      },
      "color": {"field": "location"}
    }
}

@domoritz
Copy link
Member

domoritz commented Mar 4, 2022

Thank you for putting together the example. I had implemented support for expressions in guide titles before (#7265) but have to redo it sometime (I have to redo #7438). It's in my queue.

@mdejean
Copy link

mdejean commented Mar 29, 2022

Thanks for the workaround, @jwoLondon

I can confirm this works with the existing Vega-Lite implementation, although I am not sure if it is possible to customise the axis title to be data dependent. It would be useful if axis title could accept an expression in addition to a text literal.

It seems that it already does:

Vega-Lite editor

...
"y": {
  "field": "y",
  "aggregate": "mean",
  "axis": {"title": {"expr": "measure"}}
},
...

@joelostblom
Copy link
Contributor Author

joelostblom commented Mar 29, 2022

@jwoLondon @domoritz Wow it is so cool that this works with the calculate transform and datum[param_name] syntax! 🤩 I think that largely covers the use case I wanted to have enabled when I opened this issue originally, so maybe the main thing would be to add an example to the documentation/gallery showcasing this? I think this syntax is already quite convenient and not sure I feel the need to have this open since it is already possible to do what I want in a simple way.

@mdejean Thank you for sharing that, it is working for me as well! However, if I fix the schema to version 5.2, I get an error message saying that the axis title only accepts strings (although the chart still shows, this means I can't generate the spec with Altair which checks this before displaying the chart). Was expression referencing in axis titles a recent addition after 5.2?

@kanitw
Copy link
Member

kanitw commented Mar 30, 2022

@jwoLondon that's a very nice trick!

@joelostblom
Copy link
Contributor Author

Since datum also accepts expr, maybe once #7463 is merged it would be possible to skip the calculate transform in @jwoLondon 's answer and instead use a datum containing an expr as the encoding? Something like this:

{
  "data": {"url": "data/weather.csv"},
  "params": [
    {
      "name": "measure",
      "value": "temp_max",
      "bind": {
        "input": "select",
        "options": ["temp_max", "precipitation", "wind"]
      }
    }
  ],
  "mark": "line",
  "encoding": {
    "x": {"field": "date", "timeUnit": "month"},
    "y": {
      "datum": {
        "expr": "datum[measure]"
      }
    },
    "color": {"field": "location"}
  }
}

This spec is already valid if we replace datum with value but the lines are messed up (Open the Chart in the Vega Editor). I think this is since no domain is generated for y (but a domain would be generated when using datum instead of value if I understand correctly). One problem I see is that I am not sure if it would be possible to specify the type of a datum encoding or if VegaLite could infer it as it does when scalars are past to datum?

@yclicc
Copy link

yclicc commented Jul 12, 2022

I can't find a way to repro it, but I've got a situation where the data in the data viewer has changed downstream when I use @jwoLondon 's method but a correlation calculation (don't ask) downstream and a kde plot fail to update. The underlying data in the data viewer for these dependent charts has indeed changed but the chart itself doesn't know to refresh. Is there some way (in Vega-Lite or Vega) I can explicitly tell a sub-chart to redraw when it sees a specific parameter get modified?

@yclicc
Copy link

yclicc commented Jul 13, 2022

Ok, I've got a repro with the following visualisation view here change the x variable to "displacement" and observe that the bottom KDE doesn't update. Change the value again and things get even more broken.

  "config": {"view": {"continuousWidth": 500, "continuousHeight": 500}},
  "data": {"url": "data/cars.json"},
  "usermeta": [
    "Name",
    "Miles_per_Gallon",
    "Cylinders",
    "Displacement",
    "Horsepower",
    "Weight_in_lbs",
    "Acceleration",
    "Year",
    "Origin"
  ],
  "params": [
    {
      "name": "x",
      "value": "Acceleration",
      "bind": {
        "input": "select",
        "options": [
          "Miles_per_Gallon",
          "Displacement",
          "Horsepower",
          "Weight_in_lbs",
          "Acceleration"
        ]
      }
    },
    {
      "name": "y",
      "value": "Miles_per_Gallon",
      "bind": {
        "input": "select",
        "options": [
          "Miles_per_Gallon",
          "Displacement",
          "Horsepower",
          "Weight_in_lbs",
          "Acceleration"
        ]
      }
    }
  ],
  "transform": [
    {"calculate": "datum[x]", "as": "xcalc"},
    {"calculate": "datum[y]", "as": "ycalc"}
  ],
  "hconcat": [
    {
      "mark": {"type": "area", "orient": "horizontal"},
      "width": 100,
      "params": [
        {"name": "ybrush", "select": {"type": "interval", "encodings": ["y"]}}
      ],
      "transform": [
        {"density": "ycalc", "groupby": ["Origin"], "counts": true}
      ],
      "encoding": {
        "x": {"field": "density", "type": "quantitative"},
        "y": {
          "field": "value",
          "type": "quantitative",
          "axis": {"title": {"expr": "y"}}
        },
        "color": {"field": "Origin", "type": "nominal"},
        "tooltip": {"field": "Origin", "type": "nominal"}
      }
    },
    {
      "vconcat": [
        {
          "mark": "point",
          "params": [{"name": "brush", "select": "interval"}],
          "encoding": {
            "color": {
              "condition": {
                "param": "brush",
                "field": "Origin",
                "legend": {"title": "Legend"},
                "type": "nominal"
              },
              "value": "lightgray"
            },
            "tooltip": [
              {"field": "name", "type": "nominal"},
              {"field": "year", "type": "nominal"},
              {"field": "Origin", "type": "nominal"},
              {"field": "xcalc", "type": "quantitative", "title": "x"},
              {"field": "ycalc", "type": "quantitative", "title": "y"}
            ],
            "x": {
              "field": "xcalc",
              "type": "quantitative",
              "axis": {"title": {"expr": "x"}},
              "scale": {"domain": {"param": "xbrush"}}
            },
            "y": {
              "field": "ycalc",
              "type": "quantitative",
              "axis": {"title": {"expr": "y"}},
              "scale": {"domain": {"param": "ybrush"}}
            }
          }
        },
        {
          "mark": "area",
          "height": 100,
          "params": [
            {
              "name": "xbrush",
              "select": {"type": "interval", "encodings": ["x"]}
            }
          ],
          "transform": [
            {"density": "xcalc", "groupby": ["Origin"], "counts": true}
          ],
          "encoding": {
            "x": {
              "field": "value",
              "type": "quantitative",
              "axis": {"title": {"expr": "x"}}
            },
            "y": {"field": "density", "type": "quantitative"},
            "color": {"field": "Origin", "type": "nominal"},
            "tooltip": {"field": "Origin", "type": "nominal"}
          }
        }
      ]
    }
  ]
}```

@Sebastian2023
Copy link

@jwoLondon @joelostblom Is it in Vega lite possible to select the visualized value depending on a nested field? datum[measure] from the example does not seem to be able to handle values such as Motor.Cylinder.

"data": { "values": [ { "Name": "chevrolet chevelle malibu", "Miles_per_Gallon": 18, "Motor": {"Cylinders": 8, "Horsepower": 130}, "Displacement": 307, ... "transform": [{"calculate": "datum[measure]", "as": "y"}],

Vega lite editor

@joelostblom
Copy link
Contributor Author

@domoritz Just following up on our discussion, when I try using the spec below. I run into Unsupported object: {"expr":"datum[measure]"}. I know you said there are other things in the pipeline before this, so thought I would just note it here for now.

{
  "data": {"url": "data/weather.csv"},
  "params": [
    {
      "name": "measure",
      "value": "temp_max",
      "bind": {
        "input": "select",
        "options": ["temp_max", "precipitation", "wind"]
      }
    }
  ],
  "mark": "line",
  "encoding": {
    "x": {"field": "date", "timeUnit": "month"},
    "y": {
      "datum": {
        "expr": "datum[measure]"
      },
      "type": "quantitative"
    },
    "color": {"field": "location"}
  }
}

Also @Sebastian2023 , sorry for not replying previously. Unfortunately I don't know how to make this work with a nested field.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants