Releases: vega/altair
Weekly Build 5.6.0.dev20251103
Weekly Pre-Release Build of Altair
This is a pre-release version for testing purposes.
Build Information
Version: 5.6.0.dev20251103
Tag: weekly-20251103-0f79cd8c
Previous Weekly Tag: weekly-20251027-d82683e5
Installation
From GitHub Repository (direct install)
Install directly from the tagged commit without downloading the wheel:
Command line (pip or uv):
pip install git+https://github.com/vega/altair.git@weekly-20251103-0f79cd8c
# or
uv pip install git+https://github.com/vega/altair.git@weekly-20251103-0f79cd8cAdd to pyproject.toml (pip/uv):
[project]
dependencies = [
"altair @ git+https://github.com/vega/altair.git@weekly-20251103-0f79cd8c",
]Add to pixi.toml (pixi):
[pypi-dependencies]
altair = { git = "https://github.com/vega/altair.git", rev = "weekly-20251103-0f79cd8c" }From GitHub Release (manual download)
Download the wheel file from the assets below and install:
pip install altair-5.6.0.dev20251103-py3-none-any.whlTesting & Feedback
Please note: This is a testing version. If you encounter any issues or unexpected behavior, we would greatly appreciate if you open an issue to report it. Your feedback helps improve Altair!
Weekly Build 5.6.0.dev20251027
Weekly Pre-Release Build of Altair
This is a pre-release version for testing purposes.
Build Information
Version: 5.6.0.dev20251027
Tag: weekly-20251027-d82683e5
Previous Weekly Tag: None (first build)
Installation
From GitHub Repository (direct install)
Install directly from the tagged commit without downloading the wheel:
Command line (pip or uv):
pip install git+https://github.com/vega/altair.git@weekly-20251027-d82683e5
# or
uv pip install git+https://github.com/vega/altair.git@weekly-20251027-d82683e5Add to pyproject.toml (pip/uv):
[project]
dependencies = [
"altair @ git+https://github.com/vega/altair.git@weekly-20251027-d82683e5",
]Add to pixi.toml (pixi):
[pypi-dependencies]
altair = { git = "https://github.com/vega/altair.git", rev = "weekly-20251027-d82683e5" }From GitHub Release (manual download)
Download the wheel file from the assets below and install:
pip install altair-5.6.0.dev20251027-py3-none-any.whlTesting & Feedback
Please note: This is a testing version. If you encounter any issues or unexpected behavior, we would greatly appreciate if you open an issue to report it. Your feedback helps improve Altair!
Version 5.5.0
Release 5.5.0
The Vega-Altair team is pleased to announce the release of version 5.5.0. This version introduces several exciting new features and enhancements including a revamped theme system, a new renderer optimized for screen readers, and numerous type system updates that improve auto-completion and make it easier to integrate Altair into larger typed programs.
This release adds Python 3.13 and removes Python 3.8 support. It also includes a variety of documentation improvements and a range of important bug fixes.
Thanks to our maintainers (@binste, @dangotbanned, @joelostblom, @mattijn, and @jonmmease), returning contributors (@MarcoGorelli, @daylinmorgan, and @dsmedia), and first time contributors (@jpn--, @davidgroves, and @apoorvkh) for these improvements.
What's Changed
Deprecation
alt.themes
This release deprecates the alt.themes ThemeRegistry object and replaces it with an improved theme API in the new alt.theme module.
See the updated Chart Themes documentation for more information.
Note
Usage of the legacy alt.themes registry will be supported until version 6, but will now display a warning on first use.
- Refactor
alt.themes->alt.themeby @dangotbanned in #3618 - Adds
@alt.theme.registerdecorator by @dangotbanned in #3526 - Adds
ThemeConfig(TypedDict) by @dangotbanned in #3536
Example of registering a custom theme
import altair as alt
import pandas as pd
data = pd.DataFrame({'x': [5, 3, 6, 7, 2],
'y': ['A', 'B', 'C', 'D', 'E']})
@alt.theme.register("my_little_theme", enable=True)
def custom_theme():
return alt.theme.ThemeConfig(
config={
"bar":{"color":"black"}
}
)
chart = alt.Chart(data).mark_bar().encode(
x='x',
y='y',
)
chart # enable default using `alt.theme.enable("default")`
Example of instant feedback while you define a theme config through Pylance in VSCode
Enhancements
Olli Renderer
This release integrates the Olli project to provide a chart renderer that augments chart visualizations with a keyboard-navigable structure accessible to screen readers.
- Add 'olli' renderer to generate accessible text structures for screen reader users by @binste in #3580
Example of olli renderer:
import altair as alt
from vega_datasets import data
alt.renderers.enable("olli")
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
Expressions and Selections
Several improvements were made to Altair's expression and selection APIs:
- Generate
exprmethod signatures, docs by @dangotbanned in #3600 - Support
&,|,~on all...Predicateclasses by @dangotbanned in #3668 - Support
datetime.(date|datetime)inExpression(s) by @dangotbanned in #3654 - Support
datetime.(date|datetime)as aSchemaBaseparameter by @dangotbanned in #3653 - Add missing
floattoIntoExpressionalias by @dangotbanned in #3611
Example of combining predicates within .transform_filter
import altair as alt
from vega_datasets import data
source = data.population.url
chart = alt.Chart(source).mark_line().encode(
x="age:O",
y="sum(people):Q",
color="year:O"
).transform_filter(
~alt.FieldRangePredicate(field='year', range=[1900, 1960])
& (alt.datum.age <= 70)
)
chartExample of using Python datetime.date for value in alt.selection_interval()
import datetime
import altair as alt
from vega_datasets import data
source = data.unemployment_across_industries.url
dt_values = [datetime.date(2005, 1, 1), datetime.date(2009, 1, 1)]
brush = alt.selection_interval(
encodings=['x'],
value={"x": dt_values}
)
base = alt.Chart(source).mark_area(
color='goldenrod',
opacity=0.3
).encode(
x='yearmonth(date):T',
y='sum(count):Q',
)
background = base.add_params(brush)
selected = base.transform_filter(brush).mark_area(color='goldenrod')
background + selected
Multiple predicates and constraints in Chart.transform_filter
- Support
Chart.transform_filter(*predicates, **constraints)by @dangotbanned in #3664
Example of using keyword-argument constraints to simplify filter compositions:
import altair as alt
from vega_datasets import data
source = data.population.url
chart = alt.Chart(source).mark_area().encode(
x="age:O",
y="sum(people):Q",
color="year:O"
).transform_filter(year=2000, sex=1)
chart
Bug Fixes
- Resolve multiple
@utils.use_signatureissues by @dangotbanned in #3565 - Relax
dictannotations inchannels.pyby @dangotbanned in #3573 - Set charset=UTF-8 in HTML templates. by @davidgroves in #3604
- Replace unsafe
locals()manipulation inChart.encodeby @dangotbanned in #3637 - Revise generated annotation order by @dangotbanned in #3655
- Resolve
alt.bindingsignature/docstring issues by @dangotbanned in #3671 - Add missing
@skip_requires_pyarrow(requires_tzdata=True)by @dangotbanned in #3674 - Don't materialise Ibis table to PyArrow if using vegafusion data transformer by @MarcoGorelli in #3566
mypy1.12.0 errors by @dangotbanned in #3632- Resolve warnings in
test_api.pyby @dangotbanned in #3592
Documentation
Several new examples were added to the documentation
Example of using alt.when().then().otherwise()
import altair as alt
from vega_datasets import data
source = data.cars()
brush = alt.selection_interval()
chart = alt.Chart(source).mark_point().encode(
x='Horsepower',
y='Miles_per_Gallon',
color=alt.when(brush).then("Origin").otherwise(alt.value("lightgray"))
).add_params(
brush
)
chart
Example of using luminance in an expression to dynamically colorize text
import altair as alt
from vega_datasets import data
source = data.barley()
base = alt.Chart(source).encode(
x=alt.X('sum(yield):Q').stack('zero'),
y=alt.Y('site:O').sort('-x'),
text=alt.Text('sum(yield):Q', format='.0f')
)
bars = base.mark_bar(
tooltip=alt.expr("luminance(scale('color', datum.sum_yield))")
).encode(
color='sum(yield):Q'
)
text = base.mark_text(
align='right',
dx=-3,
color=alt.expr("luminance(scale('color', datum.sum_yield)) > 0.5 ? 'black' : 'white'")
)
bars + text
- Unstack area to render cumulative chart correctly by @joelostblom in #3558
- Change remote nick to
originand capitalize version commit by @joelostblom in #3559 - Update releasing notes to reflect that main branch is now protected by @binste in #3562
- Split interactive docs section into subpages by @joelostblom in #3561
- Update docs to use correct init value for
selection_pointby @jpn-- in #3584 - Add example with overlapping bars in a grouped bar chart by @mattijn in #3612
- Bar chart with labels coloured by measured luminance by @mattijn in #3614
- Adds example Calculate Residuals by @dangotbanned in #3625
- Adds Vega-Altair Theme Test by @dangotbanned in #3630
- adds info with step size/independent scale by @daylinmorgan in #3644
- Fix "Layered chart with Dual-Axis" (Method syntax) by @dangotbanned in #3660
- Fix inaccurate
selection_intervalsignatur...
Version 5.4.1
What's Changed
Enhancements
- feat(typing): Generate
Literalaliases inchannelsoverload(s) by @dangotbanned in #3535 - feat(typing): Generate
Literal(s) using"const"by @dangotbanned in #3538
Bug Fixes
- fix: Raise informative error message if a non-existent column name is passed by @MarcoGorelli in #3533
- revert: Remove
sphinxversion constraint by @dangotbanned in #3541 - fix: Pass native dataframe to data transformers by @MarcoGorelli in #3550
- fix: Resolve
ThencopyTypeErrorby @dangotbanned in #3553
Documentation
Other Changes
- ci: bump
ruff>=0.6.0by @dangotbanned in #3539 - ci: Remove
m2rfrommypy.overridesby @dangotbanned in #3540 - refactor: Simplify
SchemaBase.copyby @dangotbanned in #3543 - fix(typing): Resolve misc type ignores in
schemapi.pyby @dangotbanned in #3545 - test: Rename test to more specific
chart_error_example__four_errors_hide_fourthby @dangotbanned in #3546 - test: Shorten
test_chart_validation_errorstest ids by @dangotbanned in #3551 - refactor: Replace an indirect
SchemaBaseimport by @dangotbanned in #3556 - test: Fix deprecation warning from
ipywidgetsby @dangotbanned in #3557
Full Changelog: v5.4.0...v5.4.1
Version 5.4.0
What's Changed
Enhancements
- Update Vega-Lite from version 5.17.0 to version 5.20.1; see Vega-Lite Release Notes. By @binste in #3479 and #3525
- Remove several dependencies to make the package more lightweight:
- feat: make pandas and NumPy optional dependencies, don't require PyArrow for plotting with Polars/Modin/cuDF by @MarcoGorelli in #3452
- Remove
toolzdependency by @dangotbanned in #3426
- feat: Improve the syntax for conditions with multiple predicates. See the documentation of
alt.whenfor examples by @dangotbanned in #3427 and #3492 - feat: Reimplement
alt.expras a class that is understood by IDEs by @dangotbanned in #3466 - feat: Support a wider range of iterables, i.e. many places in Altair now accept not only lists but
np.array,pd.Series,tuples, etc. by @dangotbanned in #3501 - feat: Adds 4 new
carbonthemes, provide autocomplete for themes by @dangotbanned in #3516 - perf: Fix issues with
Chart|LayerChart.encode, 1.32x speedup toinfer_encoding_typesby @dangotbanned in #3444
Various typing improvements:
- feat(typing): Adds public
altair.typingmodule by @dangotbanned in #3515 - feat(typing):
@deprecatedversioning, IDE highlighting by @dangotbanned in #3455 - feat: Adds
ChartTypetype and type guardis_chart_type. Change PurePath to Path type hints by @dangotbanned in #3420 - feat(typing): adds
Mapalias forMapping[str, Any]by @dangotbanned in #3458 - feat(typing): Ban
typing.Optionalimport usingruffby @dangotbanned in #3460 - feat(typing): Further simplify generated
Literalaliases by @dangotbanned in #3469 - feat(typing): Fully annotate
api.pyby @dangotbanned in #3508
Bug Fixes
- fix(typing): Resolve
mypy==1.11.0issues inplugin_registryby @dangotbanned in #3487 - fix: solve mypy errors which are due to same object names in core.py and channels.py by @binste in #3414
- fix: remove remapped
ruffrulePLR1701by @dangotbanned in #3453 - fix(docs):
@utils.use_signatureformatting by @dangotbanned in #3450 - fix(typing): Ignore
[arg-type]error in_deduplicate_enum_errorsby @dangotbanned in #3475 - fix: Restrict static & runtime top-level imports by @dangotbanned in #3482
- fix: Avoid
sphinxerror "Code Execution failed:NameError: name 'format_locale' is not defined" by @dangotbanned in #3503 - fix: replace deprecated
sphinxdefault by @dangotbanned in #3512 - fix(ruff): Bump
ruff, fixRUF031by @dangotbanned in #3529
Documentation
- docs: Versioning policy by @dangotbanned in #3488
- docs: Add example of reordering stacked bars by @joelostblom in #3395
- docs: Add example of how to create polar bar charts by @joelostblom in #3428
- docs: Add example of cumulative line chart with facet by @dsmedia in #3440
- docs: Add example with hover path and search box by @dsmedia in #3459
- docs: Add example for Bar Chart with Highlighting on Hover and Selection on Click by @dangotbanned in #3485
- docs: Link to
Vega Theme Testin user guide by @dangotbanned in #3528 - docs: Fix and improve
alt.Optionaldoc by @dangotbanned in #3449 - docs: Fix camel case of fillOpacity channel by @timtroendle in #3465
- docs: Fix
CONTRIBUTING.mdphrasing by @dangotbanned in #3477 - docs: Reduce number of items in header to 4 by @binste in #3401
- docs: Link to project board for roadmap by @joelostblom in #3404
- docs: Use raw strings with escape sequences by @joelostblom in #3411
- docs: Update
hatchguidance by @dangotbanned in #3461 - docs: Add
emptyas a explicitconditionkwarg by @dangotbanned in #3490 - docs: Undoc deprecated functionality by @dangotbanned in #3509
- docs: Remove reference to
altair_saverinsaveby @dangotbanned in #3510 - docs: Update link to Altair Ally by @sebp in #3517
Maintenance
- chore: Remove CoC link in templates since it's displayed by default by @joelostblom in #3390
- chore: Update org name from altair-viz to vega by @binste in #3400
- build: pin upperlimit geopandas by @mattijn in #3421
- ci: remove again geopandas pin and disable flaky test by @binste in #3422
- ci: Remove references to archived altair_viewer and altair_saver in ci, docs, and tests. Uninstall anywidget and vl-convert-python during one test run by @binste in #3419
- ci: prepare for
numpy 2by @dangotbanned in #3438 - ci: Add a Dependabot config to auto-update GitHub action versions by @kurtmckee in #3437
- ci: Update dependabot.yaml to include prefix by @mattijn in #3442
- ci: Bump the github-actions group with 2 updates by @dependabot in #3439
- chore: avoid pandas warning for
freq='H'in test_utils.py by @MarcoGorelli in #3446 - refactor: Add
ruffrules, improve type annotations, improve ci performance by @dangotbanned in #3431 - style: Remove outdated comments about the use of the former _Parameter protocol by @binste in #3448
- chore: fixup ruff-mypy CI job due to Ruff change by @MarcoGorelli in #3463
- refactor(typing): Reuse generated
Literalaliases inapiby @dangotbanned in #3464 - ci: remove
toolzfrom[[tool.mypy.overrides]]by @dangotbanned in #3474 - refactor: Simplify
SchemaBaserepr by @dangotbanned in #3472 - refactor: remove dead
_get_channels_mappingcode by @dangotbanned in #3467 - ci: bump
ruff>=0.5.3forPLW1514fix by @dangotbanned in #3484 - test: skip
ibistest on unsupportedpythonversion by @dangotbanned in #3486 - refactor(typing): reduce type ignores in
api.pyby @dangotbanned in #3480 - fix: remove unsupported
sphinxtheme option'footer_items'by @dangotbanned in #3489 - refactor: Rename and move
is_undefined,OneOrSeqby @dangotbanned in #3491 - refactor(docs, ruff): Add
pydocstylerules by @dangotbanned in #3493 - ci: include optional dependencies for Polars backend in ibis-framework install by @MarcoGorelli in #3494
- ci: Add
python-version=="3.9"to github action by @dangotbanned in #3498 - ci(ruff): Remove stale
docstring-code-formatcomment by @dangotbanned in #3496 - ci: relax
numpy<=2.0.0constraint by @dangotbanned in #3504 - refactor: replace archived
m2rwith updatedmistuneby @dangotbanned in #3506 - build: Add
ipykerneloptional dependency todevgroup by @dangotbanned in #3507 - refactor(ruff): Organize imports w/ (
I001,TID252) rules by @dangotbanned in #3513 - ci: Bump
sphinx,vl-convert-pythonby @dangotbanned in #3527 - chore: Remove filterwarnings from tests for cross-version pandas compatibility by @MarcoGorelli in #3522
- ci(ruff): Enforce the default
C901complexity by @dangotbanned in #3531 - refactor: Simplify unreachable compound chart cases by @dangotbanned in #3520
- feat: Adds
vega-themes.jsonusingvl_convertby @dangotbanned in #3523
New Contributors
- @dangotbanned made their first contribution in #3420
- @kurtmckee made their first contribution in #3437
- @dependabot made their first co...
Version 5.3.0
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
- Update Vega-Lite from version 5.16.3 to version 5.17.0; see Vega-Lite Release Notes
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
- Add
"jupyter"renderer which uses JupyterChart for rendering (#3283). See Displaying Altair Charts for more information. - Add
embed_optionsargument to JupyterChart to allow customization of Vega Embed options (#3304) - Add offline support for JupyterChart and the new
"jupyter"renderer. See JupyterChart - Offline Usage for more information. - Add a new section to documentation on dashboards which have support for Altair (#3299)
- Support restrictive FIPS-compliant environment (#3291)
- Simplify type-hints to improve the readability of the function signature and docstring (#3307)
- Support installation of all optional dependencies via
python -m pip install altair[all]andconda install altair-all -c conda-forge(#3354) - Add privacy friendly web-analytics for the documentation (#3350)
- Additional gallery examples and documentation clarifications (#3233, #3266, #3276, #3282, #3298, #3299, #3323, #3334, #3324, #3340, #3350, #3353, #3357, #3362, #3363), including the following:
-
altair-ex-2024-03-12_10.16.49.mp4
Bug Fixes
- Fix error when
embed_optionsareNone(#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
md5to a truncatedsha256non-cryptograhic hash (#3291) - Updated
chart.show()method to invoke the active renderer rather than depend onaltair_saver(Which was never updated for use with Altair 5) (#3379).
New Contributors
- @franzhaas made their first contribution in #3278
- @ccravens made their first contribution in #3291
- @thomascamminady made their first contribution in #3323
- @d-trigo made their first contribution in #3350
- @RobinL made their first contribution in #3383
Release notes by pull requests
Click to view all 44 PRs merged in this release
- perf: Improve performance of
Chart.from_dictby @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
alldependency 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_editormethod 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...
Version 5.2.0
What's Changed
- Update Vega-Lite from version 5.15.1 to version 5.16.3; see Vega-Lite Release Notes.
Enhancements
-
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-convertto replace the dependency onaltair_viewer. Vega-Altair 5.2.0 expectsvl-convert-pythonversion 1.1.0 or higher for this enhancement.
-
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-convertto replace the dependency onaltair_saver. Vega-Altair 5.2.0 expectsvl-convert-pythonversion 1.1.0 or higher for this enhancement.
-
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 expectsvl-convert-pythonversion 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())
-
Pass
format_localeandtime_format_localethrough 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_optionsfunction. Vega-Altair 5.2.0 expectsvl-convert-pythonversion 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!).
-
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
- @ChiaLingWeng made their first contribution in #3218
Release Notes by Pull Request
Click to view all 31 PRs merged in this release
- Perform minor consistency cleanup by @joelostblom in #3215
- [Doc] Add integers to four digit year format example by @ChiaLingWeng in #3218
- Maint: Do not pass literal json to read_json in test by @binste in #3221
- Do not display search keyboard shortcut on home page by @joelostblom in #3220
- [Doc] Add Label Position Based on Condition Example by @ChiaLingWeng in #3226
- [Doc] Update UserGuide: Add Rotate Axis, Sort Legend Example, Citing Section by @ChiaLingWeng in #3217
- [Doc] Add Show Image Marks With Selection/Show Local Images Examples by @ChiaLingWeng in #3219
- [Doc] Add Reverse Scale and Update Example for Consistency by @ChiaLingWeng in #3228
- Correct the method-based syntax for a few more gallery examples by @joelostblom in #3005
- doc: update pandas to smallcase p by @mattijn in #3232
- Type hint api.py by @binste in #3143
- maint: change to ruff for formatting by @mattijn in #3243
- maint: GitHub action include
python-version3.12 by @mattijn in #3235 - Support saving to PDF with VlConvert 1.0 by @jonmmease in #3244
- Support converting a Chart to a Vega editor URL by @jonmmease in #3252
- Type hint utils/save.py and utils/mimebundle.py by @binste in #3248
- docs: add range bar chart by @mattijn in #3250
- doc: barchart highlighting values beyond a single threshold by @mattijn in #3249
- Update image export error message with PDF format by @jonmmease in #3255
- Use vl-convert for offline html export by @jonmmease in #3251
- doc: add example interactive aggregation by @mattijn in #3260
- [Doc] Add Arrow Vector Example by @ChiaLingWeng in #3236
- [Doc] Add scatter plot with shaded area example by @ChiaLingWeng in #3256
- Make facet error more informative by @joelostblom in #3264
- Type hints: Infer types from vegalite schema for autogenerated code by @binste in #3208
- Fix broken JupyterWidget chart by pinning Vega by @jonmmease in #3269
- Type hints: Finish type hints and mark package as typed by @binste in #3272
- Update to Vega-Lite 5.16.3 by @jonmmease in #3273
- Pass locale info through to vl-convert, default to display embed options when not set by @jonmmease in #3274
- doc: add example, interval selection on a map by @mattijn in #3275
- doc: maintain colors by @mattijn in #3276
Full Changelog: v5.1.2...v5.2.0
Version 5.1.2
What's changed
-
Update Vega-Lite from version 5.14.1 to version 5.15.1; see Vega-Lite Release Notes.
-
Use Facet/Trellis/Repeat consistently in the documentation by @NickCrews in #3180
-
Add tutorial on numpy tooltip images by @joelostblom #3202
recording-2024-04-08_20.15.42.mp4
Bug Fixes
- Remove usage of deprecated Pandas parameter
convert_dtypesby @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
What's Changed
- Fix doctest and run doctests in altair module by @jonmmease in #3175
- infer dtype pandas fallback by @jonmmease in #3179
Full Changelog: v5.1.0...v5.1.1
Version 5.1.0
What's Changed
- Update Vega-Lite from version 5.8.0 to version 5.14.1; see Vega-Lite Release Notes.
Enhancements
-
The
chart.transformed_data()method was added to extract transformed chart dataFor 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

Its now possible to call thechart.transformed_datamethod to extract a pandas DataFrame containing the transformed data.chart.transformed_data()

This method is dependent on VegaFusion with the embed extras enabled.
-
Introduction of a new data transformer named
vegafusionVegaFusion 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

When thevegafusiondata 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.
-
A
JupyterChartclass was added to support accessing params and selections from PythonThe
JupyterChartclass 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

It is now possible to return the defined interval selection within Python using theJupyterChartjchart.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)

Another possibility of the newJupyerChartclass is to useIPyWidgetsto control parameters in Altair. Here we use an ipywidgetIntSliderto control the Altair parameter namedcutoff.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])

TheJupyterChartclass is dependent on AnyWidget. See a detailed overview in the new documentation page on JupyterChart Interactivity.
-
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

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

Vega-Altair support of the DataFrame Interchange Protocol is dependent on PyArrow.
-
A new transform method
transform_extentis availableSee 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
-
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)
alt.renderers.enable("png", ppi=144) # default ppi is 72 chart
Bug Fixes
- Don't call
lenon 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
- @thomend made their first contribution in #3086
- @NickCrews made their first contribution in #3155





