diff --git a/altair/vegalite/v5/api.py b/altair/vegalite/v5/api.py index 9e97e3dff..218bf0e79 100644 --- a/altair/vegalite/v5/api.py +++ b/altair/vegalite/v5/api.py @@ -2658,7 +2658,7 @@ def to_dict( validate=validate, format=format, ignore=ignore, context=context ) - def _transformed_data( + def transformed_data( self, row_limit: Optional[int] = None, exclude: Optional[Iterable[str]] = None, @@ -2859,7 +2859,7 @@ def __init__( **kwds, ) - def _transformed_data( + def transformed_data( self, row_limit: Optional[int] = None, exclude: Optional[Iterable[str]] = None, @@ -2970,7 +2970,7 @@ def __or__(self, other): copy |= other return copy - def _transformed_data( + def transformed_data( self, row_limit: Optional[int] = None, exclude: Optional[Iterable[str]] = None, @@ -3067,7 +3067,7 @@ def __or__(self, other): copy |= other return copy - def _transformed_data( + def transformed_data( self, row_limit: Optional[int] = None, exclude: Optional[Iterable[str]] = None, @@ -3164,7 +3164,7 @@ def __and__(self, other): copy &= other return copy - def _transformed_data( + def transformed_data( self, row_limit: Optional[int] = None, exclude: Optional[Iterable[str]] = None, @@ -3260,7 +3260,7 @@ def __init__(self, data=Undefined, layer=(), **kwargs): for prop in combined_dict: self[prop] = combined_dict[prop] - def _transformed_data( + def transformed_data( self, row_limit: Optional[int] = None, exclude: Optional[Iterable[str]] = None, @@ -3375,7 +3375,7 @@ def __init__( data=data, spec=spec, facet=facet, params=params, **kwargs ) - def _transformed_data( + def transformed_data( self, row_limit: Optional[int] = None, exclude: Optional[Iterable[str]] = None, diff --git a/doc/user_guide/transform/index.rst b/doc/user_guide/transform/index.rst index 7084ca50b..90ec75182 100644 --- a/doc/user_guide/transform/index.rst +++ b/doc/user_guide/transform/index.rst @@ -47,6 +47,70 @@ Transform Method :ref:`user-guide-window-transform` :meth:`~Chart.transform_window` Compute a windowed aggregation ========================================= ========================================= ================================================================================ +Accessing Transformed Data +~~~~~~~~~~~~~~~~~~~~~~~~~~ +When charts are displayed, data transformations are performed in the browser by +the Vega JavaScript library. It's often helpful to inspect transformed data +results in the process of building a chart. One approach is to display the +transformed data results in a table composed of :ref:`Text` +marks as in the :ref:`gallery_scatter_linked_table` gallery example. + +While this approach works, it's somewhat cumbersome, and still does not make it +possible to access the transformed data from Python. To make transformed data +results available in Python, Altair provides the :meth:`~Chart.transformed_data` +Chart method which integrates with `VegaFusion `_ +to evaluate data transformations in the Python kernel. + +First, install VegaFusion with the embed extras enabled. + +.. code-block:: none + + pip install "vegafusion[embed]" + +Then create an Altair chart and call the :meth:`~Chart.transformed_data` method +to extract a pandas DataFrame containing the transformed data. + +.. altair-plot:: + :output: repr + + import altair as alt + from vega_datasets import data + + cars = data.cars.url + chart = alt.Chart(cars).mark_bar().encode( + y='Cylinders:O', + x='mean_acc:Q' + ).transform_aggregate( + mean_acc='mean(Acceleration)', + groupby=["Cylinders"] + ) + chart.transformed_data() + +The :meth:`~Chart.transformed_data` method currently supports most, but not all, +of Altair's transforms. See the table below. + +========================================= ========= +Transform Supported +========================================= ========= +:ref:`user-guide-aggregate-transform` ✔ +:ref:`user-guide-bin-transform` ✔ +:ref:`user-guide-calculate-transform` ✔ +:ref:`user-guide-density-transform` +:ref:`user-guide-filter-transform` ✔ +:ref:`user-guide-flatten-transform` +:ref:`user-guide-fold-transform` ✔ +:ref:`user-guide-impute-transform` ✔ +:ref:`user-guide-joinaggregate-transform` ✔ +:ref:`user-guide-loess-transform` +:ref:`user-guide-lookup-transform` +:ref:`user-guide-pivot-transform` ✔ +:ref:`user-guide-quantile-transform` +:ref:`user-guide-regression-transform` +:ref:`user-guide-sample-transform` +:ref:`user-guide-stack-transform` ✔ +:ref:`user-guide-timeunit-transform` ✔ +:ref:`user-guide-window-transform` ✔ +========================================= ========= .. toctree:: :hidden: diff --git a/tests/test_transformed_data.py b/tests/test_transformed_data.py index 1604f2026..928b539f5 100644 --- a/tests/test_transformed_data.py +++ b/tests/test_transformed_data.py @@ -60,7 +60,7 @@ def test_primitive_chart_examples(filename, rows, cols): source = pkgutil.get_data(examples_methods_syntax.__name__, filename) chart = eval_block(source) - df = chart._transformed_data() + df = chart.transformed_data() assert len(df) == rows assert set(cols).issubset(set(df.columns)) @@ -101,7 +101,7 @@ def test_compound_chart_examples(filename, all_rows, all_cols): chart = eval_block(source) print(chart) - dfs = chart._transformed_data() + dfs = chart.transformed_data() assert len(dfs) == len(all_rows) for df, rows, cols in zip(dfs, all_rows, all_cols): assert len(df) == rows @@ -119,7 +119,7 @@ def test_transformed_data_exclude(): ) chart = (bar + rule + some_annotation).properties(width=600) - datasets = chart._transformed_data(exclude=["some_annotation"]) + datasets = chart.transformed_data(exclude=["some_annotation"]) assert len(datasets) == 2 assert len(datasets[0]) == 52