Skip to content

Releases: vega/altair

Version 5.3.0

30 Mar 15:36
Compare
Choose a tag to compare

The Vega Project is happy to announce the release of version 5.3.0 of the Vega-Altair Python visualization library. This release has been 4 months in the making and includes enhancements, fixes, and documentation improvements from 11 contributors.

What's Changed

Enhancements

  • Add integration of VegaFusion and JupyterChart to enable scaling many interactive Vega-Altair charts to millions of rows. See VegaFusion Data Transformer for more information. Here is an example of histogram cross filtering with a 1 million row dataset.

    vegafusion_widget.mov
  • Add "browser" renderer to support displaying Vega-Altair charts in an external web browser. See Browser Renderer for more information (#3379).

    browser_renderer.mov
  • Support opening charts in the Vega editor with chart.open_editor() (#3358)

    open_editor.mov

Bug Fixes

  • Fix error when embed_options are None (#3376)
  • Fix type hints for libraries such as Polars where Altair uses the dataframe interchange protocol (#3297)
  • Fix anywidget deprecation warning (#3364)
  • Fix handling of Date32 columns in arrow tables and Polars DataFrames (#3377)

Backward-Incompatible Changes

  • Changed hash function from md5 to a truncated sha256 non-cryptograhic hash (#3291)
  • Updated chart.show() method to invoke the active renderer rather than depend on altair_saver (Which was never updated for use with Altair 5) (#3379).

New Contributors

Release notes by pull requests

Click to view all 44 PRs merged in this release
  • perf: Improve performance of Chart.from_dict by @RobinL in #3383
  • feature: Add browser renderer to open charts in external browser and update chart.show() to display chart by @jonmmease in #3379
  • fix: Don't error when embed_options are None by @jonmmease in #3376
  • fix: Handle Date32 columns in Arrow tables and Polars DataFrames by @jonmmease in #3377
  • fix: Support falling back to pandas when pyarrow is installed but too old by @jonmmease in #3387
  • docs: Remove release notes and fully capture them in GitHub Releases by @binste in #3380
  • Update save.py to use utf-8 instead of None per default by @franzhaas in #3278
  • Consolidate governance documents in Vega Organization by @domoritz in #3277
  • doc: histogram with gradient color by @mattijn in #3282
  • Update for FIPS Compliance by @ccravens in #3291
  • Docs: Fix link to project governance docs by @binste in #3298
  • Fix type checker errors for libraries such as Polars where Altair uses dataframe interchange protocol by @binste in #3297
  • Integrate VegaFusion into JupyterChart by @jonmmease in #3281
  • Add "jupyter" renderer based on JupyterChart by @jonmmease in #3283
  • Docs: Add section on displaying Altair charts in dashboards by @binste in #3299
  • Validate version of vegafusion-python-embed by @jonmmease in #3303
  • Add embed_options to JupyterChart and pass them through in "jupyter" renderer by @jonmmease in #3304
  • Add offline support to JupyterChart and "jupyter" renderer by @jonmmease in #3305
  • Type hints: Simplify to improve user experiences by @binste in #3307
  • Adding missing interpolation methods to Line example by @thomascamminady in #3323
  • Docs: Link to new section on Altair in Plotly docs by @binste in #3324
  • Docs: Mark completed items in roadmap by @binste in #3326
  • Docs: Mention Marimo in Dashboards section by @binste in #3334
  • Relax type hint for 'indent' in to_json method by @binste in #3342
  • MAINT: Reformat codebase with new style of ruff 0.3.0 by @binste in #3345
  • Docs: Add another version of the 'Multiline Tooltip' exmaple which uses the standard tooltip by @binste in #3340
  • Docs: Add privacy-friendly web analytics with plausible by @binste in #3346
  • Docs: Modifying scale of "multiple interactions" example and adding legend adjustments by @d-trigo in #3350
  • Add example of how to update titles based on a selection parameters by @joelostblom in #3353
  • Add all dependency group by @jonmmease in #3354
  • Add timeseries filtering example to illustrate subsetting of columns from selector values by @joelostblom in #3357
  • Fix anywidget deprecation warning by @jonmmease in #3364
  • Clarifications to the interactive docs by @joelostblom in #3362
  • Open charts in the default browser with open_editor method by @joelostblom in #3358
  • Change "mouse" to "pointer" everywhere by @joelostblom in #3363
  • doc: update numpy-tooltip-images.rst by @mattijn in #3233
  • Change a couple of more additional occurences of pointer over by @joelostblom in #3368
  • [Doc] Fix Chart and MarkDef language by @ChiaLingWeng in #3266
  • Add remaining changelog entries for 5.3 by @joelostblom in #3369
  • Upgrade to Vega-Lite 5.17.0 by @binste in #3367
  • Add a few 5.3 changelog entries by @jonmmease in #3372
  • Add note about conda "all" installation and how to install without optional dependencies by @joelostblom in #3373
  • Update README badges to reflect updated tool chain by @mattijn in #3374
  • chore: Add templates for PRs and automated release notes by @joelostblom in https://github.com/altair-vi...
Read more

Version 5.2.0

28 Nov 06:23
Compare
Choose a tag to compare

What's Changed

Enhancements

  1. Support offline HTML export using vl-convert (#3251)

    You now can use:

    chart.save('chart.html', inline=True)
    

    To create an HTML file with inline JavaScript dependencies. This enhancements takes advantage of HTML bundling support in vl-convert to replace the dependency on altair_viewer. Vega-Altair 5.2.0 expects vl-convert-python version 1.1.0 or higher for this enhancement.


  2. Support saving charts as PDF files using the vl-convert export engine (#3244)

    You now can use:

    chart.save('chart.pdf')
    

    To create an PDF representation of your chart. This enhancements takes advantage of PDF support in vl-convert to replace the dependency on altair_saver. Vega-Altair 5.2.0 expects vl-convert-python version 1.1.0 or higher for this enhancement.


  3. Support converting charts to sharable Vega editor URLs with chart.to_url() (#3252)

    You now can use:

    chart.to_url()
    

    To generate a Vega editor URL that opens the chart's specification in the online Vega editor. This enhancements takes advantage of lz-string URL-compatible compression in vl-convert. Vega-Altair 5.2.0 expects vl-convert-python version 1.1.0 or higher for this enhancement.

    Example:

    import altair as alt
    from vega_datasets import data
    
    chart = alt.Chart(data.cars.url).mark_point().encode(
        x='Horsepower:Q',
        y='Miles_per_Gallon:Q',
        color='Origin:N'
    )
    
    print(chart.to_url())

    https://vega.github.io/editor/#/url/vega-lite/N4Igxg9gdgZglgcxALlANzgUwO4tJKAFzigFcJSBnAdTgBNCALFAZgAY2AacaYsiygAlMiRoVYcAvpO50AhoTl4QpAE4AbFCDGEADpWQB6Q2DpQAdACtKdTOrhpV5qJkKGougLaG0mBHIBaeUVKV0oAATQARnMAJgBOczZDYLkTOVVKK0poEBkQTwyAa2VCAE9dTC1dCBJxfMwoSDoSJFQedQhVZXg7Oi0AeVVEEhBucsqtKAhPEjlNfIAPHqx1fuQQQS7QmuxMbvGKqo2AR1I5IjhFYl887jKVvq0AWTh1TEoAfUrVT4BxeadKBjEATY4gM4XYjXBxVaTcAAklDAjEwhS0On0Rh8fjk5gQV0YpAARuY4BBDMjUYUcf4AvZCJgfABWcxRABs5hY2VykiAA


  4. Pass format_locale and time_format_locale through to vl-convert to support locales in static image export (#3274)

    The preferred format of numbers, dates, and currencies varies by language and locale. Vega-Altair takes advantage of D3’s localization support to make it easy to configure the locale for your chart using the global alt.renderers.set_embed_options function. Vega-Altair 5.2.0 expects vl-convert-python version 1.1.0 or higher for this enhancement.

    See https://altair-viz.github.io/user_guide/customization.html#localization for more info (including the note with a caveat!).


  5. Vega-Altair is now a typed package, with type annotations for all public functions and classes and some of the internal code

    See #2951 for a full summary how we have implemented these. Type hints can help IDEs to provide a better development experience as well as static type checkers to catch potential errors before they appear at runtime.

Maintenance

  • Vega-Altair now uses ruff for maintaining code quality & consistency (#3243)
  • Vega-Altair is tested against Python 3.12 (#3235)

Bug Fixes

  • None

Backward-Incompatible Changes

  • None

New Contributors

Release Notes by Pull Request

Click to view all 31 PRs merged in this release

Full Changelog: v5.1.2...v5.2.0

Version 5.1.2

03 Oct 18:18
Compare
Choose a tag to compare

What's changed

Bug Fixes

  • Remove usage of deprecated Pandas parameter convert_dtypes by @binste in #3191
  • Fix encoding type inference for boolean columns when pyarrow is installed by @jonmmease in #3210

Full Changelog: v5.1.1...v5.1.2

Version 5.1.1

30 Aug 11:35
Compare
Choose a tag to compare

What's Changed

Full Changelog: v5.1.0...v5.1.1

Version 5.1.0

28 Aug 14:14
Compare
Choose a tag to compare

What's Changed

Enhancements

  1. The chart.transformed_data() method was added to extract transformed chart data

    For example when having an Altair chart including aggregations:

    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

    image
    Its now possible to call the chart.transformed_data method to extract a pandas DataFrame containing the transformed data.

    chart.transformed_data()

    image
    This method is dependent on VegaFusion with the embed extras enabled.


  2. Introduction of a new data transformer named vegafusion

    VegaFusion is an external project that provides efficient Rust implementations of most of Altair's data transformations. Using VegaFusion as Data Transformer it can overcome the Altair MaxRowsError by performing data-intensive aggregations in Python and pruning unused columns from the source dataset.

    The data transformer can be enabled as such:

    import altair as alt
    alt.data_transformers.enable("vegafusion") # default is "default"
    DataTransformerRegistry.enable('vegafusion')

    And one can now visualize a very large DataFrame as histogram where the binning is done within VegaFusion:

    import pandas as pd
    import altair as alt
    
    # prepare dataframe with 1 million rows
    flights = pd.read_parquet(
        "https://vegafusion-datasets.s3.amazonaws.com/vega/flights_1m.parquet"
    )
    
    delay_hist = alt.Chart(flights).mark_bar(tooltip=True).encode(
        alt.X("delay", bin=alt.Bin(maxbins=30)),
        alt.Y("count()")
    )
    delay_hist

    image
    When the vegafusion data transformer is active, data transformations will be pre-evaluated when displaying, saving and converting charts as dictionary or JSON.

    See a detailed overview on the VegaFusion Data Transformer in the documentation.


  3. A JupyterChart class was added to support accessing params and selections from Python

    The JupyterChart class makes it possible to update charts after they have been displayed and access the state of interactions from Python.

    For example when having an Altair chart including a selection interval as brush:

    import altair as alt
    from vega_datasets import data
    
    source = data.cars()
    brush = alt.selection_interval(name="interval", value={"x": [80, 160], "y": [15, 30]})
    
    chart = alt.Chart(source).mark_point().encode(
        x='Horsepower:Q',
        y='Miles_per_Gallon:Q',
        color=alt.condition(brush, 'Cylinders:O', alt.value('grey')),
    ).add_params(brush)
    
    jchart = alt.JupyterChart(chart)
    jchart

    image
    It is now possible to return the defined interval selection within Python using the JupyterChart

    jchart.selections.interval.value
    {'Horsepower': [80, 160], 'Miles_per_Gallon': [15, 30]}

    The selection dictionary may be converted into a pandas query to filter the source DataFrame:

    filter = " and ".join([
        f"{v[0]} <= `{k}` <= {v[1]}"
        for k, v in jchart.selections.interval.value.items()
    ])
    source.query(filter)

    image
    Another possibility of the new JupyerChart class is to use IPyWidgets to control parameters in Altair. Here we use an ipywidget IntSlider to control the Altair parameter named cutoff.

    import pandas as pd
    import numpy as np
    from ipywidgets import IntSlider, link, VBox
    
    rand = np.random.RandomState(42)
    
    df = pd.DataFrame({
        'xval': range(100),
        'yval': rand.randn(100).cumsum()
    })
    
    cutoff = alt.param(name="cutoff", value=23)
    
    chart = alt.Chart(df).mark_point().encode(
        x='xval',
        y='yval',
        color=alt.condition(
            alt.datum.xval < cutoff,
            alt.value('red'), alt.value('blue')
        )
    ).add_params(
        cutoff
    )
    jchart = alt.JupyterChart(chart)
    
    slider = IntSlider(min=0, max=100, description='ipywidget')
    link((slider, "value"), (jchart.params, "cutoff"))
    
    VBox([slider, jchart])

    image
    The JupyterChart class is dependent on AnyWidget. See a detailed overview in the new documentation page on JupyterChart Interactivity.


  4. Support for field encoding inference for objects that support the DataFrame Interchange Protocol

    We are maturing support for objects build upon the DataFrame Interchange Protocol in Altair.
    Given the following pandas DataFrame with an ordered categorical column-type:

    import altair as alt
    from vega_datasets import data
    
    # Clean Title column
    movies = data.movies()
    movies["Title"] = movies["Title"].astype(str)
    
    # Convert MPAA rating to an ordered categorical
    rating = movies["MPAA_Rating"].astype("category")
    rating = rating.cat.reorder_categories(
        ['Open', 'G', 'PG', 'PG-13', 'R', 'NC-17', 'Not Rated']
    ).cat.as_ordered()
    movies["MPAA_Rating"] = rating
    
    # Build chart using pandas
    chart = alt.Chart(movies).mark_bar().encode(
        alt.X("MPAA_Rating"),
        alt.Y("count()")
    )
    chart

    image
    We can convert the DataFrame to a PyArrow Table and observe that the types are now equally infered when rendering the chart.

    import pyarrow as pa
    
    # Build chart using PyArrow
    chart = alt.Chart(pa.Table.from_pandas(movies)).mark_bar().encode(
        alt.X("MPAA_Rating"),
        alt.Y("count()")
    )
    chart

    image
    Vega-Altair support of the DataFrame Interchange Protocol is dependent on PyArrow.


  5. A new transform method transform_extent is available

    See the following example how this transform can be used:

    import pandas as pd
    import altair as alt
    
    df = pd.DataFrame(
        [
            {"a": "A", "b": 28},
            {"a": "B", "b": 55},
            {"a": "C", "b": 43},
            {"a": "D", "b": 91},
            {"a": "E", "b": 81},
            {"a": "F", "b": 53},
            {"a": "G", "b": 19},
            {"a": "H", "b": 87},
            {"a": "I", "b": 52},
        ]
    )
    
    base = alt.Chart(df, title="A Simple Bar Chart with Lines at Extents").transform_extent(
        extent="b", param="b_extent"
    )
    bars = base.mark_bar().encode(x="b", y="a")
    lower_extent_rule = base.mark_rule(stroke="firebrick").encode(
        x=alt.value(alt.expr("scale('x', b_extent[0])"))
    )
    upper_extent_rule = base.mark_rule(stroke="firebrick").encode(
        x=alt.value(alt.expr("scale('x', b_extent[1])"))
    )
    bars + lower_extent_rule + upper_extent_rule

    image


  6. It is now possible to add configurable pixels-per-inch (ppi) metadata to saved and displayed PNG images

    import altair as alt
    from vega_datasets import data
    
    source = data.cars()
    
    chart = alt.Chart(source).mark_boxplot(extent="min-max").encode(
        alt.X("Miles_per_Gallon:Q").scale(zero=False),
        alt.Y("Origin:N"),
    )
    chart.save("box.png", ppi=300)

    image

    alt.renderers.enable("png", ppi=144) # default ppi is 72
    chart

    image

Bug Fixes

  • Don't call len on DataFrame Interchange Protocol objects (#3111)

Maintenance

  • Add support for new referencing logic in version 4.18 of the jsonschema package

Backward-Incompatible Changes

  • Drop support for Python 3.7 which is end-of-life (#3100)
  • Hard dependencies: Increase minimum required pandas version to 0.25 (#3130)
  • Soft dependencies: Increase minimum required vl-convert-python version to 0.13.0 and increase minimum required vegafusion version to 1.4.0 (#3163, #3160)

New Contributors

Release Notes by Pull Request

Click to view all 52 PRs m...
Read more

Version 5.0.1

26 May 21:55
Compare
Choose a tag to compare

What's Changed

Full Changelog: v5.0.0...v5.0.1

Version 5.0.0

09 May 15:04
Compare
Choose a tag to compare

What's Changed

Enhancements

  • As described in the release notes for Vega-Lite 5.0.0, the primary change in this release of Altair is the introduction of parameters. There are two types of parameters, selection parameters and variable parameters. Variable parameters are new to Altair, and while selections are not new, much of the old terminology has been deprecated. See Slider Cutoff for an application of variable parameters (#2528).
  • Grouped bar charts and jitter are now supported using offset channels, see Grouped Bar Chart with xOffset and Strip Plot Jitter.
  • vl-convert is now used as the default backend for saving Altair charts as svg and png files, which simplifies saving chart as it does not require external dependencies like altair_saver does (#2701). Currently, altair_saver does not support Altair 5 and it is recommended to switch to vl-convert. See PNG, SVG, and PDF format for more details.
  • Saving charts with HTML inline is now supported without having altair_saver installed (#2807).
  • The default chart width was changed from 400 to 300 (#2785).
  • Ordered pandas categorical data are now automatically encoded as sorted ordinal data (#2522)
  • The Title and Impute aliases were added for TitleParams and ImputeParams, respectively (#2732).
  • The documentation page has been revamped, both in terms of appearance and content.
  • More informative autocompletion by removing deprecated methods (#2814) and for editors that rely on type hints (e.g. VS Code) we added support for completion in method chains (#2846) and extended keyword completion to cover additional methods (#2920).
  • Substantially improved error handling. Both in terms of finding the more relevant error (#2842), and in terms of improving the formatting and clarity of the error messages (#2824, #2568, #2979, #3009).
  • Include experimental support for the DataFrame Interchange Protocol (through __dataframe__ attribute). This requires pyarrow>=11.0.0 (#2888).
  • Support data type inference for columns with special characters (#2905).
  • Responsive width support using width="container" when saving charts to html or displaying them with the default html renderer (#2867).

Grammar Changes

  • Channel options can now be set via a more convenient method-based syntax in addition to the previous attribute-based syntax. For example, instead of alt.X(..., bin=alt.Bin(...)) it is now recommend to use alt.X(...).bin(...)) (#2795). See Method-Based Syntax for details.
  • selection_single and selection_multi are now deprecated; use selection_point instead. Similarly, type=point should be used instead of type=single and type=multi.
  • add_selection is deprecated; use add_params instead.
  • The selection keyword argument must in many cases be replaced by param (e.g., when specifying a filter transform).
  • The empty keyword argument for a selection parameter should be specified as True or False instead of all or none, respectively.
  • The init keyword argument for a parameter is deprecated; use value instead.

Bug Fixes

  • Displaying a chart not longer changes the shorthand syntax of the stored spec (#2813).
  • Fixed disable_debug_mode (#2851).
  • Fixed issue where the webdriver was not working with Firefox's geckodriver (#2466).
  • Dynamically determine the jsonschema validator to avoid issues with recent jsonschema versions (#2812).

Backward-Incompatible Changes

  • Colons in column names must now be escaped to remove any ambiguity with encoding types. You now need to write "column\:name" instead of "column:name" (#2824).
  • Removed the Vega (v5) wrappers and deprecate rendering in Vega mode (save Chart as Vega format is still allowed) (#2829).
  • Removed the Vega-Lite 3 and 4 wrappers (#2847).
  • Removed the deprecated datasets.py (#3010).
  • In regards to the grammar changes listed above, the old terminology will still work in many basic cases. On the other hand, if that old terminology gets used at a lower level, then it most likely will not work. For example, in the current version of Scatter Plot with Minimap, two instances of the key param are used in dictionaries to specify axis domains. Those used to be selection, but that usage is not compatible with the current Vega-Lite schema.
  • Removed the altair.sphinxext module (#2792). The altair-plot Sphinx directive is now part of the sphinxext-altair package.

Maintenance

  • Vega-Altair now uses hatch for package management.
  • Vega-Altair now uses ruff for linting.

New Contributors

Release Notes by Pull Request

Click to view all 203 PRs merged in this release
Read more

Version 4.2.2

27 Jan 23:10
Compare
Choose a tag to compare

Bug Fixes

  • Fix incompatibility with jsonschema < 4.5 which got introduced in Altair 4.2.1 (#2860).

Full Changelog: v4.2.1...v4.2.2

Version 4.2.1

26 Jan 23:04
Compare
Choose a tag to compare

Note: This version requires jsonschema>=4.5.0 see (#2857).

Bug Fixes

  • Disable uri-reference format check in jsonsschema (#2771).
  • Replace iteritems with items due to pandas deprecation (#2683).

Maintenance

  • Add deprecation and removal warnings for Vega-Lite v3 wrappers and Vega v5 wrappers (#2843).

Version 4.2.0

29 Dec 13:30
Compare
Choose a tag to compare

Enhancements

Bug Fixes

  • Fix to_dict() for nested selections (#2120).
  • Fix item access for expressions (#2099).