Description
openedon Jul 7, 2023
Relates to #313. For layered and multi-view charts, Altair takes a bit of a shortcut and does not use the exact classes which map to the Vega-Lite schema but instead uses the API convenience classes such as alt.Chart
, alt.LayerChart
, etc. For example for the layered chart below, the elements of layer
are alt.Chart
instances:
import altair as alt
import vegafusion as vf
from vega_datasets import data
source = data.wheat()
bar = alt.Chart(source).mark_bar().encode(
x='year:O',
y='wheat:Q'
)
rule = alt.Chart(source).mark_rule(color='red').encode(
y='mean(wheat):Q'
)
layer_chart = (bar + rule).properties(width=600)
type(layer_chart.layer[0]) # altair.vegalite.v5.api.Chart
However, when reconstructing this chart from a dictionary, the layers are of type UnitSpec
which is the correct class following the VL schema:
reconstructed_layer_chart = alt.Chart.from_dict(layer_chart.to_dict())
type(reconstructed_layer_chart.layer[0]) # altair.vegalite.v5.schema.core.UnitSpec
When calling transformed_data
on the reconstructed chart, it fails as the isinstance
checks do not accept UnitSpec
as an equivalent to alt.Chart
although it should be:
vf.transformed_data(reconstructed_layer_chart)
ValueError: transformed_data accepts an instance of Chart, FacetChart, LayerChart, HConcatChart, VConcatChart, or ConcatChart
Received value of type: <class 'altair.vegalite.v5.schema.core.UnitSpec'>
All classes which I think can be treated as equivalent to the first one mentioned in every bullet:
- Chart: TopLevelUnitSpec (parent class of Chart), FacetedUnitSpec, UnitSpec, UnitSpecWithFrame, NonNormalizedSpec (used in concat charts for chart objects in e.g.
hconcat
attribute) - LayerChart: TopLevelLayerSpec (parent class of LayerChart), LayerSpec
- RepeatChart: TopLevelRepeatSpec (parent class of RepeatChart), RepeatSpec
- ConcatChart: TopLevelConcatSpec (parent class of ConcatChart), ConcatSpecGenericSpec
- HConcatChart: TopLevelHConcatSpec (parent class of HConcatChart), HConcatSpecGenericSpec
- VConcatChart: TopLevelVConcatSpec (parent class of VConcatChart), VConcatSpecGenericSpec
- FacetChart: TopLevelFacetSpec (parent class of FacetChart), FacetSpec
Spec classes which I'm not sure about but we can probably ignore as repeat charts are not supported yet by transformed_data
anyway:
- LayerRepeatSpec
- NonLayerRepeatSpec
- GenericUnitSpecEncodingAnyMark
Just a reminder that the same changes would need to be applied to https://github.com/altair-viz/altair/blob/master/altair/utils/_transformed_data.py.
Btw, my use case for the above is that a frontend sends the chart specifications as a JSON to a backend API which executes vf.transformed_data(alt.Chart.from_dict(spec))
and then returns the extracted data as an Excel file to the user of the web application.