<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <id>https://vegafusion.io</id>
  <title>VegaFusion Blog - Posts in Release</title>
  <updated>2024-11-25T23:29:15.777254+00:00</updated>
  <link href="https://vegafusion.io"/>
  <link href="https://vegafusion.io/posts/category/release/atom.xml" rel="self"/>
  <generator uri="https://ablog.readthedocs.io/" version="0.11.12">ABlog</generator>
  <subtitle>VegaFusion Updates</subtitle>
  <entry>
    <id>https://vegafusion.io/posts/2024/2024-11-13_Release_2.0.0.html</id>
    <title>VegaFusion 2.0</title>
    <updated>2024-11-13T00:00:00-05:00</updated>
    <author>
      <name>Jon Mease</name>
    </author>
    <content type="html">&lt;section id="vegafusion-2-0"&gt;

&lt;p&gt;&lt;strong&gt;A new era: Building blocks for analyzing, accelerating, and scaling Vega visualizations:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By: Jon Mease&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;The VegaFusion team is excited to announce the release of VegaFusion 2.0. This major release represents a significant evolution in VegaFusion’s architecture and target audience. The focus has been on simplification - making VegaFusion easier to maintain and easier to integrate into larger Vega systems to accelerate and scale Vega visualizations.&lt;/p&gt;
&lt;section id="modernized-rust-core"&gt;
&lt;h2&gt;Modernized Rust Core&lt;/h2&gt;
&lt;p&gt;The core Rust implementation has been significantly simplified by taking advantage of modern DataFusion functionality:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_column_usage()&lt;/span&gt;&lt;/code&gt; utility function for analyzing the column dependencies of datasets in a Vega spec.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Custom User Defined Functions (UDFs) have been largely replaced with DataFusion’s native capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vega transforms are now implemented directly against the DataFusion DataFrame API, rather than using the circuitous SQL generation approach of VegaFusion 1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updated to DataFusion 43 and Arrow 52.3 for improved performance and bug fixes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="javascript-webassembly"&gt;
&lt;h2&gt;JavaScript / WebAssembly&lt;/h2&gt;
&lt;p&gt;The JavaScript integration has been simplified while maintaining full functionality:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Removed the separate &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion-embed&lt;/span&gt;&lt;/code&gt; package as the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion-wasm&lt;/span&gt;&lt;/code&gt; package now renders charts using vega-embed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The full VegaFusion runtime is now compiled to WebAssembly as part of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion-wasm&lt;/span&gt;&lt;/code&gt; pacakge, making it possible to run VegaFusion entirely in the browser without requiring an external server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connecting to external VegaFusion servers via gRPC-Web remains supported.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="python-removal-of-upstreamed-vega-altair-integration"&gt;
&lt;h2&gt;Python: Removal of Upstreamed Vega-Altair Integration&lt;/h2&gt;
&lt;p&gt;All the VegaFusion 1.x logic for integrating with Vega-Altair has been upstreamed into the Vega-Altair project itself. So this functionality has been removed in VegaFusion 2.0.&lt;/p&gt;
&lt;p&gt;In particular:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;To use VegaFusion with Vega-Altair, activate the &lt;a class="reference external" href="https://altair-viz.github.io/user_guide/large_datasets.html#vegafusion-data-transformer"&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;quot;vegafusion&amp;quot;&lt;/span&gt;&lt;/code&gt; data transformer&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion-jupyter&lt;/span&gt;&lt;/code&gt; package has been retired in favor of using Altair’s built-in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;JupyterChart&lt;/span&gt;&lt;/code&gt; for Altair charts and Vega-Lite specs. For Vega specs, the new &lt;a class="reference external" href="https://anywidget.dev/"&gt;AnyWidget&lt;/a&gt;-based &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VegaFusionWidget&lt;/span&gt;&lt;/code&gt; is included in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion&lt;/span&gt;&lt;/code&gt; package.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vf.enable()&lt;/span&gt;&lt;/code&gt; has been removed. Instead, use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;quot;vegafusion&amp;quot;&lt;/span&gt;&lt;/code&gt; data transformer along with any of Altair’s built-in renderers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vf.save()&lt;/span&gt;&lt;/code&gt; has been removed. Instead, use Altair’s native &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;chart.save()&lt;/span&gt;&lt;/code&gt; method with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;quot;vegafusion&amp;quot;&lt;/span&gt;&lt;/code&gt; data transformer enabeld.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vf.transformed_data()&lt;/span&gt;&lt;/code&gt; has been removed. Instead, use Altair’s native &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;chart.transformed_data()&lt;/span&gt;&lt;/code&gt; method.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="python-enhanced-dataframe-compatibility"&gt;
&lt;h2&gt;Python: Enhanced DataFrame Compatibility&lt;/h2&gt;
&lt;p&gt;VegaFusion 2.0 brings improved DataFrame compatibility:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Support for any &lt;a class="reference external" href="https://narwhals-dev.github.io/narwhals/"&gt;Narwhals&lt;/a&gt;-compatible DataFrame type as inline datasets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Zero-copy sharing of Arrow data from Polars to VegaFusion’s DataFusion runtime is now supported thanks to the &lt;a class="reference external" href="https://github.com/kylebarron/arro3"&gt;arro3&lt;/a&gt; project..&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The DuckDB SQL connection has been removed, but DuckDB relations are now directly supported as inline datasets, with automatic column pruning prior to conversion to Arrow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduced Python dependencies. VegaFusion now requires only &lt;a class="reference external" href="https://pypi.org/project/arro3-core/"&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;arrow3-core&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;, &lt;a class="reference external" href="https://pypi.org/project/packaging/"&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;packaging&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;, and &lt;a class="reference external" href="https://pypi.org/project/narwhals/"&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;narwhals&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;. In particular, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pyarrow&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pandas&lt;/span&gt;&lt;/code&gt; are no longer required dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="new-documentation"&gt;
&lt;h2&gt;New Documentation&lt;/h2&gt;
&lt;p&gt;VegaFusion 2.0 launches with completely revamped documentation:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New PyData Sphinx theme at &lt;a class="reference external" href="http://vegafusion.io/v2/"&gt;vegafusion.io&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Standalone examples in Python and Rust&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Comprehensive support tables for Vega transforms and expressions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="learn-more"&gt;
&lt;h2&gt;Learn more&lt;/h2&gt;
&lt;p&gt;Check out these resources to learn more:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/releases/tag/v2.0.0"&gt;2.0.0 Changelog&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vegafusion.io/v2"&gt;VegaFusion Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion"&gt;VegaFusion GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/issues"&gt;Report and Issue&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/discussions"&gt;Start a Discussion&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://vegafusion.io/posts/2024/2024-11-13_Release_2.0.0.html"/>
    <summary>A new era: Building blocks for analyzing, accelerating, and scaling Vega visualizations:</summary>
    <published>2024-11-13T00:00:00-05:00</published>
  </entry>
  <entry>
    <id>https://vegafusion.io/posts/2023/2023-08-21_Release_1.4.0.html</id>
    <title>VegaFusion 1.4</title>
    <updated>2023-08-21T00:00:00-04:00</updated>
    <author>
      <name>Jon Mease</name>
    </author>
    <content type="html">&lt;section id="vegafusion-1-4"&gt;

&lt;p&gt;&lt;strong&gt;Improved Vega coverage, external data source foundations, extended architecture support&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By: Jon Mease&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;The VegaFusion team is happy to announce the release of version 1.4. Along with the usual bug fixes and updates to the core Arrow and DataFusion dependencies, this release improves coverage of Vega’s features by supporting &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;q1&lt;/span&gt;&lt;/code&gt;/&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;q3&lt;/span&gt;&lt;/code&gt; aggregation functions and bitwise operators. It also lays important foundations for supporting external data sources and compute engines, and adds additional architectures for pip and conda packages.&lt;/p&gt;
&lt;section id="improved-vega-coverage"&gt;
&lt;h2&gt;Improved Vega coverage&lt;/h2&gt;
&lt;p&gt;VegaFusion 1.4 adds support for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;q1&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;q3&lt;/span&gt;&lt;/code&gt; aggregation functions. This makes it possible for VegaFusion to evaluate all the transforms associated with a Vega-Lite boxplot. Here’s a Vega-Altair example:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;vega_datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cars&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_boxplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;min-max&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Miles_per_Gallon:Q&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zero&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Origin:N&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="boxplot" src="https://github.com/vegafusion/vegafusion.github.io/assets/15064365/acf29249-314d-4582-8176-80110690d452" /&gt;&lt;/p&gt;
&lt;p&gt;An easy way to see that the transforms are supported is to extract the transformed data with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vf.transformed_data&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transformed_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head text-right"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-left"&gt;&lt;p&gt;Origin&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;lower_box_Miles_per_Gallon&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;upper_box_Miles_per_Gallon&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;mid_box_Miles_per_Gallon&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;lower_whisker_Miles_per_Gallon&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;upper_whisker_Miles_per_Gallon&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;USA&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;15&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;24&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;18.5&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;9&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;39&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Europe&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;24&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;30.65&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;26.5&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;16.2&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;44.3&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Japan&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;25.7&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;34.05&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;31.6&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;18&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;46.6&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;In addition, the full complement of bitwise operators are now supported in the Vega expression language including &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;|&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;amp;&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;^&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;/code&gt;, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="external-data-source-foundations"&gt;
&lt;h2&gt;External Data Source Foundations&lt;/h2&gt;
&lt;p&gt;VegaFusion 1.4 lays some important foundations toward the goal of supporting external data sources and compute engines. The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion.dataset.sql.SqlDataset&lt;/span&gt;&lt;/code&gt; abstract class defines the interface for implementing SQL data sources in Python for any of VegaFusion’s 10 supported SQL dialects. Implementations for DuckDB and Snowpark are also provided. In addition, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion.dataset.DataFrameDataset&lt;/span&gt;&lt;/code&gt; abstract class defines the interface for implementing VegaFusion’s data transformations with external DataFrame libraries. Motivating examples include the future ability to dispatch VegaFusion data transformations to the &lt;a class="reference external" href="https://ibis-project.org/"&gt;Ibis&lt;/a&gt; and &lt;a class="reference external" href="https://www.pola.rs/"&gt;Polars&lt;/a&gt; Python libraries.&lt;/p&gt;
&lt;p&gt;In the coming release of Vega-Altair 5.1, it will be possible to pass implementations of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SqlDataset&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DataFrameDataset&lt;/span&gt;&lt;/code&gt; to Altair &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Chart&lt;/span&gt;&lt;/code&gt; objects instead of pandas DataFrames. Stay tuned for more information and examples after the release of Altair 5.1!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="extended-architecture-support"&gt;
&lt;h2&gt;Extended Architecture Support&lt;/h2&gt;
&lt;p&gt;VegaFusion wheels are now built and published to PyPI for the aarch64 Linux architecture. In addition, conda-forge packages are now published for the Apple Silicon architecture.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="updates-to-arrow-and-datafusion-dependencies"&gt;
&lt;h2&gt;Updates to Arrow and DataFusion dependencies&lt;/h2&gt;
&lt;p&gt;VegaFusion 1.4 updates the dependency on arrow-rs to &lt;a class="reference external" href="https://github.com/apache/arrow-rs/blob/master/CHANGELOG-old.md#4200-2023-06-16"&gt;version 42.0.0&lt;/a&gt; and DataFusion to &lt;a class="reference external" href="https://github.com/apache/arrow-datafusion/blob/main/dev/changelog/27.0.0.md"&gt;version 27.0.0&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="looking-ahead"&gt;
&lt;h2&gt;Looking ahead&lt;/h2&gt;
&lt;p&gt;The coming release of Vega-Altair 5.1 will include first-class integration with VegaFusion to support extracting transformed data from a chart with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;chart.transformed_data()&lt;/span&gt;&lt;/code&gt;. It will also include a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;quot;vegafusion&amp;quot;&lt;/span&gt;&lt;/code&gt; data transformer that will cause Altair to use VegaFusion to pre-evaluate data transformations and remove unused columns when saving or displaying charts. The timeline has not been decided on yet, but the plan is to eventually deprecate VegaFusion’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transformed_data&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;save_*&lt;/span&gt;&lt;/code&gt; functions and the VegaFusion mime renderer in favor of the integrations built into Altair.&lt;/p&gt;
&lt;p&gt;Another near-term focus is on lowering the barrier to contributing to VegaFusion by adopting the &lt;a class="reference external" href="https://prefix.dev/docs/pixi/overview"&gt;Pixi&lt;/a&gt; environment manager.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="learn-more"&gt;
&lt;h2&gt;Learn more&lt;/h2&gt;
&lt;p&gt;Check out these resources to learn more:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/releases/tag/v1.4.0"&gt;1.4.0 Changelog&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vegafusion.io/"&gt;VegaFusion Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion"&gt;VegaFusion GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/issues"&gt;Report and Issue&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/discussions"&gt;Start a Discussions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://vegafusion.io/posts/2023/2023-08-21_Release_1.4.0.html"/>
    <summary>Improved Vega coverage, external data source foundations, extended architecture support</summary>
    <published>2023-08-21T00:00:00-04:00</published>
  </entry>
  <entry>
    <id>https://vegafusion.io/posts/2023/2023-06-10_Release_1.3.0.html</id>
    <title>VegaFusion 1.3</title>
    <updated>2023-06-10T00:00:00-04:00</updated>
    <author>
      <name>Jon Mease</name>
    </author>
    <content type="html">&lt;section id="vegafusion-1-3"&gt;

&lt;p&gt;&lt;strong&gt;Transformed data for compound charts, Java library&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By: Jon Mease&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;The VegaFusion team is happy to announce the release of version 1.3. Along with usual bug fixes and updates to the core Arrow and DataFusion dependencies, this release includes an enhancement to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transformed_data&lt;/span&gt;&lt;/code&gt; function to make it compatible with compound charts, adds DuckDB 0.8 support, and adds a new Java API.&lt;/p&gt;
&lt;section id="extract-transformed-data-from-compound-altair-charts"&gt;
&lt;h2&gt;Extract transformed data from compound Altair charts&lt;/h2&gt;
&lt;p&gt;The VegaFusion &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transformed_data&lt;/span&gt;&lt;/code&gt; function can be used to extract the transformed data from an Altair chart object as a pandas DataFrame. Prior to 1.3.0, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transformed_data&lt;/span&gt;&lt;/code&gt; was only supported on simple charts that involve only a single mark. Now, compound layered and concatenated charts are supported as well. In the case of a compound chart, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transformed_data&lt;/span&gt;&lt;/code&gt; will return a list of pandas DataFrame’s rather than single DataFrame.&lt;/p&gt;
&lt;section id="example-histogram-with-a-global-mean-overlay"&gt;
&lt;h3&gt;Example: Histogram with a Global Mean Overlay&lt;/h3&gt;
&lt;p&gt;Here is an example based on the &lt;a class="reference external" href="https://altair-viz.github.io/gallery/histogram_with_a_global_mean_overlay.html"&gt;Histogram with a Global Mean Overlay&lt;/a&gt; example from the Altair gallery.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;vega_datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;

&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;movies&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;

&lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;IMDB_Rating:Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;count()&amp;#39;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_rule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;red&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mean(IMDB_Rating):Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="Rule on Histogram" src="https://github.com/vegafusion/vegafusion.github.io/assets/15064365/645a52a1-0b37-4b0a-9da1-1f7d348c1527" /&gt;&lt;/p&gt;
&lt;p&gt;Because &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;chart&lt;/span&gt;&lt;/code&gt; is composed of two subcharts, the result of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vf.transformed_data&lt;/span&gt;&lt;/code&gt; will be a list of two DataFrames.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;hist_df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rule_df&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transformed_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;hist_df&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;bin_maxbins_10_IMDB_Rating&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;bin_maxbins_10_IMDB_Rating_end&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;__count&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|---&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;|-----------------------------&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;|---------------------------------&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;|----------&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="mi"&gt;985&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="mi"&gt;741&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="mi"&gt;633&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="mi"&gt;43&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="mi"&gt;273&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                               &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;rule_df&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;mean_IMDB_Rating&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|---&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;|-------------------&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="mf"&gt;6.28347&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="duckdb-0-8-support"&gt;
&lt;h2&gt;DuckDB 0.8 Support&lt;/h2&gt;
&lt;p&gt;VegaFusion’s DuckDB integration has been updated to support DuckDB 0.8.0&lt;/p&gt;
&lt;/section&gt;
&lt;section id="java-api"&gt;
&lt;h2&gt;Java API&lt;/h2&gt;
&lt;p&gt;VegaFusion 1.3 may now be embedded in Java applications using the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;io.vegafusion.vegafusion&lt;/span&gt;&lt;/code&gt; jar, which is published to &lt;a class="reference external" href="https://central.sonatype.com/artifact/io.vegafusion/vegafusion"&gt;Maven Central&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This was accomplished by wrapping the VegaFusion Rust API with a JNI interface using the &lt;a class="reference external" href="https://github.com/jni-rs/jni-rs"&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;jni-rs&lt;/span&gt;&lt;/code&gt; crate&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="updates-to-arrow-and-datafusion-dependencies"&gt;
&lt;h2&gt;Updates to Arrow and DataFusion dependencies&lt;/h2&gt;
&lt;p&gt;VegaFusion 1.3 updates the dependency on arrow-rs to &lt;a class="reference external" href="https://github.com/apache/arrow-rs/blob/master/CHANGELOG-old.md#3900-2023-05-05"&gt;version 39.0&lt;/a&gt; and DataFusion to &lt;a class="reference external" href="https://github.com/apache/arrow-datafusion/blob/main/dev/changelog/25.0.0.md"&gt;version 25.0&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="learn-more"&gt;
&lt;h2&gt;Learn more&lt;/h2&gt;
&lt;p&gt;Check out these resources to learn more:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/releases/tag/v1.3.0"&gt;1.3.0 Changelog&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vegafusion.io/"&gt;VegaFusion Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion"&gt;VegaFusion GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/issues"&gt;Report and Issue&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/discussions"&gt;Start a Discussions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://vegafusion.io/posts/2023/2023-06-10_Release_1.3.0.html"/>
    <summary>Transformed data for compound charts, Java library</summary>
    <published>2023-06-10T00:00:00-04:00</published>
  </entry>
  <entry>
    <id>https://vegafusion.io/posts/2023/2023-04-12_Release_1.2.0.html</id>
    <title>VegaFusion 1.2</title>
    <updated>2023-04-12T00:00:00-04:00</updated>
    <author>
      <name>Jon Mease</name>
    </author>
    <content type="html">&lt;section id="vegafusion-1-2"&gt;

&lt;p&gt;&lt;strong&gt;Pre-transform and Save Altair Charts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By: Jon Mease&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;The VegaFusion team is happy to announce the release of version 1.2. Along with usual bug fixes and updates to the core Arrow and DataFusion dependencies, this release includes support for saving pre-transformed Altair charts to HTML, JSON, PNG, and SVG files.&lt;/p&gt;
&lt;section id="standard-altair-save"&gt;
&lt;h2&gt;Standard Altair save&lt;/h2&gt;
&lt;p&gt;Altair Charts provide a &lt;a class="reference external" href="https://altair-viz.github.io/user_guide/saving_charts.html"&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Chart.save()&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; method that may be used to save Altair charts to HTML, JSON, or static image (PNG or SVG) files. When the chart references a pandas DataFrame, the full DataFrame is serialized to JSON and included in the chart specification that is saved.  As dataset sizes get larger, the time it takes to save these files increases rapidly, and for the case of HTML and JSON formats, the file size increases rapidly as well.&lt;/p&gt;
&lt;p&gt;VegaFusion’s new save functions improve the situation by pre-applying data transformations and removing unused columns before inlining the resulting data in the chart specification for saving.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="html-performance-comparison"&gt;
&lt;h2&gt;HTML performance comparison&lt;/h2&gt;
&lt;p&gt;Here are two examples of the benefits of the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;save_html&lt;/span&gt;&lt;/code&gt; function compared to the standard Altair &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Chart.save&lt;/span&gt;&lt;/code&gt; method.&lt;/p&gt;
&lt;section id="with-aggregations"&gt;
&lt;h3&gt;With aggregations&lt;/h3&gt;
&lt;p&gt;Let’s save a one million row histogram chart to an HTML file. First create and display the histogram with the VegaFusion Mime Renderer enabled.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;flights&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_parquet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;https://vegafusion-datasets.s3.amazonaws.com/vega/flights_1m.parquet&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;delay_hist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flights&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;delay&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxbins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;count()&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;delay_hist&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="histogram" src="https://user-images.githubusercontent.com/15064365/230728055-64b05777-9925-4711-b7c4-3e4cc52e1c83.png" /&gt;&lt;/p&gt;
&lt;p&gt;Next, save the chart to an HTML file with the standard Altair &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Chart.save&lt;/span&gt;&lt;/code&gt; method.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;%%&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="n"&gt;delay_hist&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;delay_hist_standard.html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;CPU&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="mf"&gt;5.72&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;388&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;6.11&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="n"&gt;Wall&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;6.18&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This results in a ~116MB file, as all columns from the entire million row dataset are included in the HTML file. It also takes over 6 seconds to perform the save. Now, use VegaFusion’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;save_html&lt;/span&gt;&lt;/code&gt; function.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;%%&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay_hist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;delay_hist_vf.html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;CPU&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="mi"&gt;227&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;119&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;347&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;
&lt;span class="n"&gt;Wall&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;427&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The resulting file is now only ~5KB, because only ~30 rows have been included (one per histogram bin). It also takes under half a second to perform the save.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="without-aggregations"&gt;
&lt;h3&gt;Without aggregations&lt;/h3&gt;
&lt;p&gt;The benefits of VegaFusion’s new save functions are most dramatic for charts that use aggregations. Even so, VegaFusion’s ability to remove unused columns still results in smaller file sizes for unaggregated charts, especially when the input datasets have many unused columns.&lt;/p&gt;
&lt;p&gt;Here’s an example scatter chart using the movies dataset from the vega-datasets package, which has 3201 rows and 16 columns.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;vega_datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;

&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;movies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;scatter_chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_point&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;IMDB_Rating:Q&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Rotten_Tomatoes_Rating:Q&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;scatter_chart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="movies scatter chart" src="https://user-images.githubusercontent.com/15064365/230728307-6d8a2c6c-e45e-483b-a207-3abf0c26449b.png" /&gt;&lt;/p&gt;
&lt;p&gt;Save the chart to an HTML file with Altair’s standard &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Chart.save&lt;/span&gt;&lt;/code&gt; method.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;%%&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="n"&gt;scatter_chart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;scatter_standard.html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;CPU&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="mf"&gt;69.7&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;14.7&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;84.4&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;
&lt;span class="n"&gt;Wall&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;85&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This results in a 1.4MB file and takes ~80ms.&lt;/p&gt;
&lt;p&gt;Now, save the file with VegaFusion’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;save_html&lt;/span&gt;&lt;/code&gt; function.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;%%&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scatter_chart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;scatter_vf.html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;CPU&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="mf"&gt;59.8&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;15.2&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;
&lt;span class="n"&gt;Wall&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;57.1&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This results in a 125K file and takes under 60ms. The file is more than 10x smaller because it only includes data for the two columns that are referenced by the scatter plot.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="updates-to-arrow-and-datafusion-dependencies"&gt;
&lt;h2&gt;Updates to Arrow and DataFusion dependencies&lt;/h2&gt;
&lt;p&gt;VegaFusion 1.2 updates the dependency on arrow-rs to &lt;a class="reference external" href="https://github.com/apache/arrow-rs/blob/master/CHANGELOG-old.md#3400-2023-02-24"&gt;version 36.0&lt;/a&gt; and DataFusion to &lt;a class="reference external" href="https://github.com/apache/arrow-datafusion/blob/main/dev/changelog/22.0.0.md"&gt;version 22.0&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="learn-more"&gt;
&lt;h2&gt;Learn more&lt;/h2&gt;
&lt;p&gt;Check out these resources if you’d like to learn more:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vegafusion.io/"&gt;VegaFusion Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion"&gt;VegaFusion GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/issues"&gt;Report and Issue&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/discussions"&gt;Start a Discussions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://vegafusion.io/posts/2023/2023-04-12_Release_1.2.0.html"/>
    <summary>Pre-transform and Save Altair Charts</summary>
    <published>2023-04-12T00:00:00-04:00</published>
  </entry>
  <entry>
    <id>https://vegafusion.io/posts/2023/2023-03-25_Release_1.1.0.html</id>
    <title>VegaFusion 1.1</title>
    <updated>2023-03-25T00:00:00-04:00</updated>
    <author>
      <name>Jon Mease</name>
    </author>
    <content type="html">&lt;section id="vegafusion-1-1"&gt;

&lt;p&gt;&lt;strong&gt;DuckDB and Polars support, Altair 5 compatibility, and lots of bug fixes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By: Jon Mease&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;The VegaFusion team is happy to announce the release of version 1.1. In addition to the usual slew of bug fixes, this release includes support for evaluating Vega transforms in DuckDB, support for Polars and the DataFrame Interchange Protocol, and forward compatibility with the coming release of Altair 5.&lt;/p&gt;
&lt;section id="duckdb-support"&gt;
&lt;h2&gt;DuckDB support&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://duckdb.org/"&gt;DuckDB&lt;/a&gt; is an in-process SQL OLAP query engine and database that provides bindings for a wide variety of languages, including Python. The VegaFusion 1.1 Python library now includes two forms of integration with DuckDB. First, it can use DuckDB in place of DataFusion to power Vega transforms over the pandas DataFrames that are referenced by Altair charts. Second, VegaFusion 1.1 makes it possible to reference externally defined DuckDB tables and views in Altair charts.&lt;/p&gt;
&lt;section id="vega-transforms-with-duckdb"&gt;
&lt;h3&gt;Vega transforms with DuckDB&lt;/h3&gt;
&lt;p&gt;VegaFusion can now be configured to evaluate Vega transforms using the DuckDB Python library by calling &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion.runtime.set_connection(&amp;quot;duckdb&amp;quot;)&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once the DuckDB connection is enabled, pandas DataFrames referenced by Altair charts are automatically registered with DuckDB and Vega transforms are translated into DuckDB SQL queries. Here is a full example, adapted from the &lt;a class="reference external" href="https://altair-viz.github.io/gallery/histogram_heatmap.html"&gt;2D Histogram Heatmap&lt;/a&gt; Altair gallery example.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;

&lt;span class="c1"&gt;# Configure DuckDB connection&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;duckdb&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Enable Mime Renderer&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Load 201k row version of the Vega movies dataset with pandas&lt;/span&gt;
&lt;span class="n"&gt;movies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_parquet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;https://vegafusion-datasets.s3.amazonaws.com/vega/movies_201k.parquet&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create an Altair chart from the pandas DataFrame as usual.&lt;/span&gt;
&lt;span class="c1"&gt;# Binning and aggregation will be evaluated against the DataFrame with DuckDB&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_rect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;IMDB_Rating:Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxbins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Rotten_Tomatoes_Rating:Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxbins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;count():Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;greenblue&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="2D Histogram Heatmap" src="https://user-images.githubusercontent.com/15064365/226609213-2eba5e0b-1377-47d1-9ca9-32dc8f43fb8c.png" /&gt;&lt;/p&gt;
&lt;p&gt;Additionally, the transformed data can be extracted as usual:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transformed_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row_limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;0&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;3&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;4&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;bin_maxbins_60_IMDB_Rating&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;3.4&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;5.8&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.4&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;bin_maxbins_60_IMDB_Rating_end&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;3.6&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;6&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.2&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.2&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.6&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;bin_maxbins_40_Rotten_Tomatoes_Rating&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;60&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;25&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;85&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;80&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;80&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;bin_maxbins_40_Rotten_Tomatoes_Rating_end&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;65&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;30&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;90&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;85&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;85&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;__count&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;63&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;441&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;504&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;1260&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;1134&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;The default DataFusion connection can be re-enabled by calling &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion.runtime.set_connection(&amp;quot;datafusion&amp;quot;)&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;section id="performance-benefit"&gt;
&lt;h4&gt;Performance benefit&lt;/h4&gt;
&lt;p&gt;DuckDB has the ability to perform queries against Pandas DataFrames without first serializing them to Arrow. This can result in 10x+ speedups when visualizing large Pandas DataFrames with the VegaFusion Mime Renderer.  Presently, the VegaFusion Widget Renderer always serializes DataFrames to Arrow and writes them to disk, so significant performance gains are not expected for the Widget Renderer.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="access-duckdb-tables"&gt;
&lt;h3&gt;Access DuckDB tables&lt;/h3&gt;
&lt;p&gt;VegaFusion 1.1 also supports integration with external DuckDB connections, making it possible to reference DuckDB tables and views from Altair charts.  To begin, import &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;duckdb&lt;/span&gt;&lt;/code&gt; and create a new connection.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;duckdb&lt;/span&gt;
&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;duckdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pass this DuckDB connection to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion.runtime.set_connection&lt;/span&gt;&lt;/code&gt; (instead of the string &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;quot;duckdb&amp;quot;&lt;/span&gt;&lt;/code&gt; as in the previous example).&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Next, use the DuckDB connection to create a table or view. Here, the DuckDB &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_parquet&lt;/span&gt;&lt;/code&gt; method is used to load the 201k row movies dataset, and a DuckDB query is used to filter NULL values. The result of this query is registered as a table named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;movies&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;relation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_parquet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;https://vegafusion-datasets.s3.amazonaws.com/vega/movies_201k.parquet&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;relation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;tbl&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="s2"&gt;    SELECT * FROM tbl &lt;/span&gt;
&lt;span class="s2"&gt;    WHERE Rotten_Tomatoes_Rating IS NOT NULL AND Imdb_Rating IS NOT NULL&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;movies&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;DuckDB tables and views registered with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;conn&lt;/span&gt;&lt;/code&gt; may be referenced from Altair charts with a special URL syntax using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;table://&lt;/span&gt;&lt;/code&gt; as the prefix. To reference the DuckDB table named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;movies&lt;/span&gt;&lt;/code&gt;, the Altair chart should be passed the url string &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;quot;table://movies&amp;quot;&lt;/span&gt;&lt;/code&gt;. Here is a full example&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;duckdb&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;

&lt;span class="c1"&gt;# Create DuckDB connection&lt;/span&gt;
&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;duckdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Pass DuckDB connection to VegaFusion&amp;#39;s set_connection method&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Enable Mime Renderer&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Read parquet file using the DuckDB connection&lt;/span&gt;
&lt;span class="n"&gt;relation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_parquet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;https://vegafusion-datasets.s3.amazonaws.com/vega/movies_201k.parquet&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Filter NULL values and register the result as a table named &amp;quot;movies&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;relation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;tbl&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="s2"&gt;    SELECT * FROM tbl &lt;/span&gt;
&lt;span class="s2"&gt;    WHERE Rotten_Tomatoes_Rating IS NOT NULL AND Imdb_Rating IS NOT NULL&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;movies&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create an Altair chart that references the registered DuckDB table&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;table://movies&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_rect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;IMDB_Rating:Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxbins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Rotten_Tomatoes_Rating:Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxbins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;count():Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;greenblue&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="2D Histogram Heatmap" src="https://user-images.githubusercontent.com/15064365/226609213-2eba5e0b-1377-47d1-9ca9-32dc8f43fb8c.png" /&gt;&lt;/p&gt;
&lt;p&gt;See the DuckDB connection docs for more information.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="polars-support"&gt;
&lt;h2&gt;Polars support&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.pola.rs/"&gt;Polars&lt;/a&gt; describes itself as a “Lightning-fast DataFrame library for Rust and Python”. Polars has quickly &lt;a class="reference external" href="https://star-history.com/#pola-rs/polars&amp;amp;amp;Date"&gt;gained popularity&lt;/a&gt; as a faster alternative to pandas that also supports larger datasets.&lt;/p&gt;
&lt;p&gt;VegaFusion’s new Polars integration makes it possible to input and output Polars DataFrames without conversion through pandas.&lt;/p&gt;
&lt;section id="polars-as-input"&gt;
&lt;h3&gt;Polars as Input&lt;/h3&gt;
&lt;p&gt;Here is a full example that uses Polars to read the 201k row movies dataset from a remote parquet file. The DataFrame’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;filter&lt;/span&gt;&lt;/code&gt; method is then used to remove rows with NULL movie rating values. This filtered DataFrame is passed as the input to an Altair chart.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;polars&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pl&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;

&lt;span class="c1"&gt;# Enable Mime Renderer&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Load 201k movies parquet dataset&lt;/span&gt;
&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_parquet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;https://vegafusion-datasets.s3.amazonaws.com/vega/movies_201k.parquet&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Fitler out rows with null ratings&lt;/span&gt;
&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;IMDB_Rating&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_not_null&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Rotten_Tomatoes_Rating&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_not_null&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create chart&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_circle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;IMDB_Rating:Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Rotten_Tomatoes_Rating:Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;count()&amp;#39;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="visualization" src="https://user-images.githubusercontent.com/15064365/226755752-c88e37a5-80a8-4ccd-85d0-554974079cb6.png" /&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="polars-as-output"&gt;
&lt;h3&gt;Polars as Output&lt;/h3&gt;
&lt;p&gt;When a Chart that references a Polars DataFrame is passed to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion.transformed_data&lt;/span&gt;&lt;/code&gt;, the result will also be a Polars DataFrame. Here is a Polars version of the example from the Transformed Data section.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;polars&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;pl&lt;/span&gt;

&lt;span class="c1"&gt;# Enable mime renderer&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Load 201k movies parquet dataset with Polars&lt;/span&gt;
&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_parquet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;https://vegafusion-datasets.s3.amazonaws.com/vega/movies_201k.parquet&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Build chart&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_aggregate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;aggregate_gross&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mean(Worldwide_Gross)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;groupby&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Director&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;row_number()&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SortField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;aggregate_gross&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;descending&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;ranked_director&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;datum.rank &amp;lt; 10 ? datum.Director : &amp;#39;All Others&amp;#39;&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;aggregate_gross:Q&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;aggregate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mean&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s2"&gt;&amp;quot;ranked_director:N&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mean&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;aggregate_gross&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;descending&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Top Directors by Average Worldwide Gross&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="visualization (4)" src="https://user-images.githubusercontent.com/15064365/209851553-b6af2a14-affe-4a54-ba17-2590bdbc957d.png" /&gt;&lt;/p&gt;
&lt;p&gt;Now retrieve the chart’s transformed data as a Polars DataFrame.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;transformed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transformed_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transformed&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;transformed&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&amp;lt;class &amp;#39;polars.internals.dataframe.frame.DataFrame&amp;#39;&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;shape: (10, 2)&lt;/p&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head text-left"&gt;&lt;p&gt;ranked_director (str)&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;mean_aggregate_gross (f64)&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;David Yates&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;9.37984e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;James Cameron&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;8.29781e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Carlos Saldanha&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.69293e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Pete Docter&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.31305e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Andrew Stanton&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.00319e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;David Slade&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;6.88155e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;George Lucas&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;6.73577e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Andrew Adamson&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;6.43134e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Peter Jackson&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;5.95566e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;All Others&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;8.87602e+07&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;See the Polars Integration docs for more information.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dataframe-interchange-protocol"&gt;
&lt;h2&gt;DataFrame Interchange Protocol&lt;/h2&gt;
&lt;p&gt;The “Polars as Input” workflow above is powered by a more general abstraction: The &lt;a class="reference external" href="https://data-apis.org/dataframe-protocol/latest/index.html"&gt;DataFrame Interchange Protocol&lt;/a&gt;. Along with Altair 5, VegaFusion 1.1 adds support for inputting any DataFrame object that supports this protocol including pyarrow Tables, Vaex DataFrames, cuDF DataFrames, and more.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="altair-5-compatibility"&gt;
&lt;h2&gt;Altair 5 Compatibility&lt;/h2&gt;
&lt;p&gt;Along with Altair 5.0.0rc1, VegaFusion 1.1 updates Vega-Lite from 4.17.0 to 5.6.1. This is a significant update that enables many new features for Altair users. For more info, see the &lt;a class="reference external" href="https://altair-viz.github.io/"&gt;Altair 5 docs&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="learn-more"&gt;
&lt;h2&gt;Learn more&lt;/h2&gt;
&lt;p&gt;Check out these resources if you’d like to learn more:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vegafusion.io/"&gt;VegaFusion Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion"&gt;VegaFusion GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/issues"&gt;Report and Issue&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/discussions"&gt;Start a Discussions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://vegafusion.io/posts/2023/2023-03-25_Release_1.1.0.html"/>
    <summary>DuckDB and Polars support, Altair 5 compatibility, and lots of bug fixes</summary>
    <published>2023-03-25T00:00:00-04:00</published>
  </entry>
  <entry>
    <id>https://vegafusion.io/posts/2023/2023-01-21_Release_1.0.0.html</id>
    <title>VegaFusion 1.0</title>
    <updated>2023-01-21T00:00:00-05:00</updated>
    <author>
      <name>Jon Mease</name>
    </author>
    <content type="html">&lt;section id="vegafusion-1-0"&gt;

&lt;p&gt;&lt;strong&gt;Mime renderer, transform evaluation, and a permissive license&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By: Jon Mease&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;The VegaFusion team is happy to announce the release of VegaFusion version 1.0. This release is the culmination of several months of work on both VegaFusion itself and its new dependency: &lt;a class="reference external" href="https://medium.com/&amp;#64;jonmmease/introducing-vlconvert-c763f0076e89"&gt;VlConvert&lt;/a&gt;.  This version introduces a brand new mimetype based renderer that is compatible with many notebook and compute environments without requiring custom extensions. It also includes a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transformed_data()&lt;/span&gt;&lt;/code&gt; function that makes it possible to evaluate the data transforms associated with an Altair &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Chart&lt;/span&gt;&lt;/code&gt; and return the result as a pandas DataFrame.&lt;/p&gt;
&lt;p&gt;Finally, we’re thrilled to announce that VegaFusion has been adopted by Hex and is now licensed under the same permissive BSD-3 license used by Vega, Vega-Lite, and Altair.&lt;/p&gt;
&lt;section id="background"&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;VegaFusion scales Vega, Vega-Lite, and Altair visualizations by moving data transformations from the browser to a server (e.g. a Python kernel).&lt;/p&gt;
&lt;p&gt;The initial focus was on supporting complex interactive visualizations that require a live two-way connection between the client and server.  This approach works well, but it relies on a custom Jupyter widget extension which adds complexity and limits the environments it can be deployed in.&lt;/p&gt;
&lt;p&gt;To reduce complexity while addressing the more common scenario of non-interactive charts, VegaFusion 1.0 introduces an entirely new renderer that does not require any custom extensions but instead leverages the built-in rendering capabilities of modern notebooks and compute environments.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="vegafusion-mime-renderer"&gt;
&lt;h2&gt;VegaFusion mime renderer&lt;/h2&gt;
&lt;p&gt;Altair comes with a default limit of 5,000 input rows to avoid crashing the user’s browser. Because all data transformations are applied in the browser by the Vega JavaScript library, the full input dataset must be loaded into the browser.  The VegaFusion mime renderer performs most common Vega transforms in the Python kernel, and so the row limit is applied to the transformed data rather than the input data. When the chart includes any form of aggregation, the transformed dataset typically has many fewer rows than the input dataset.&lt;/p&gt;
&lt;p&gt;To use the VegaFusion mime renderer, first install the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion&lt;/span&gt;&lt;/code&gt; Python package with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;embed&lt;/span&gt;&lt;/code&gt; extras enabled:&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-U&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;vegafusion[embed]&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then open a Jupyter notebook (either the classic notebook or a notebook inside JupyterLab), and create an Altair histogram of a 1 million row flights dataset&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;

&lt;span class="n"&gt;flights&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_parquet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;https://vegafusion-datasets.s3.amazonaws.com/vega/flights_1m.parquet&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;delay_hist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flights&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;delay&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxbins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;count()&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;delay_hist&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;---------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="n"&gt;MaxRowsError&lt;/span&gt;                              &lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;MaxRowsError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;greater&lt;/span&gt; &lt;span class="n"&gt;than&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;maximum&lt;/span&gt; &lt;span class="n"&gt;allowed&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;information&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;plot&lt;/span&gt; &lt;span class="n"&gt;larger&lt;/span&gt; &lt;span class="n"&gt;datasets&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Altair&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;see&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;documentation&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As expected, this results in an Altair &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;MaxRowsError&lt;/span&gt;&lt;/code&gt;. The VegaFusion mime renderer can be used to overcome this limitation by performing data intensive transforms (e.g. filtering, binning, aggregation, etc.) in the Python kernel before the resulting data is sent to the web browser.&lt;/p&gt;
&lt;p&gt;Run these two lines to import and enable the new VegaFusion mime renderer:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now the chart displays quickly without errors:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;delay_hist&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="Flight Delay Histogram" src="https://user-images.githubusercontent.com/15064365/209973961-948b9d10-4202-4547-bbc8-d1981dcc8c4e.png" /&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="transform-evaluation"&gt;
&lt;h2&gt;Transform evaluation&lt;/h2&gt;
&lt;p&gt;VegaFusion now supports extracting the transformed data for an Altair Chart using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion.transformed_data()&lt;/span&gt;&lt;/code&gt; function. This is particularly useful when building a chart that includes a pipeline of transforms, as it’s now possible to see the intermediate results of each transform step.&lt;/p&gt;
&lt;section id="example-top-k"&gt;
&lt;h3&gt;Example: Top K&lt;/h3&gt;
&lt;p&gt;Here is an example, based on the &lt;a class="reference external" href="https://altair-viz.github.io/gallery/top_k_with_others.html"&gt;Top-K plot with Others&lt;/a&gt; example from the Altair documentation, of how &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transformed_data()&lt;/span&gt;&lt;/code&gt; can be helpful when building a complex chart.&lt;/p&gt;
&lt;p&gt;First, create an Altair &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Chart&lt;/span&gt;&lt;/code&gt; wrapping the data source URL.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;

&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;https://cdn.jsdelivr.net/npm/vega-datasets@v1.29.0/data/movies.json&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transformed_data()&lt;/span&gt;&lt;/code&gt; function can be used on this empty chart to access a preview of the data that is available at the URL. Here the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;row_limit&lt;/span&gt;&lt;/code&gt; argument is used to limit the result to 3 rows and the DataFrame is transposed to make it easier to read.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transformed_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row_limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-left"&gt;&lt;p&gt;0&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-left"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-left"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Title&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;The Land Girls&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;First Love, Last Rites&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;I Married a Strange Person&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;US_Gross&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;146083&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;10876&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;203134&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Worldwide_Gross&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;146083&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;10876&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;203134&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Production_Budget&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;8000000&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;300000&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;250000&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Release_Date&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Jun 12 1998&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Aug 07 1998&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Aug 28 1998&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;MPAA_Rating&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Distributor&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Gramercy&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Strand&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Lionsgate&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;IMDB_Rating&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;6.1&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;6.9&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;6.8&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;IMDB_Votes&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;1071.0&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;207.0&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;865.0&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Major_Genre&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Drama&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Comedy&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Rotten_Tomatoes_Rating&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;nan&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;nan&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;nan&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Source&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Creative_Type&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Director&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-left"&gt;&lt;p&gt;US_DVD_Sales&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;nan&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;nan&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;nan&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-left"&gt;&lt;p&gt;Running_Time_min&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;nan&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;nan&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;nan&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;The first step of making this chart is to compute the average worldwide gross of all the movies for each director. This can be accomplished with the Altair &lt;a class="reference external" href="https://altair-viz.github.io/user_guide/transform/aggregate.html"&gt;Aggregate Transform&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_aggregate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;aggregate_gross&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mean(Worldwide_Gross)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;groupby&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Director&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transformed_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row_limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head text-right"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-left"&gt;&lt;p&gt;Director&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;aggregate_gross&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;3.59284e+07&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Christopher Nolan&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;3.44251e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Roman Polanski&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;5.13407e+07&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Richard Fleischer&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;2.27635e+07&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;4&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Blake Edwards&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;5e+06&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Next, the directors are ranked by average gross in descending order. This can be accomplished with the Altair &lt;a class="reference external" href="https://altair-viz.github.io/user_guide/transform/window.html"&gt;Window Transform&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_aggregate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;aggregate_gross&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mean(Worldwide_Gross)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;groupby&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Director&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;row_number()&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SortField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;aggregate_gross&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;descending&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transformed_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row_limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head text-right"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-left"&gt;&lt;p&gt;Director&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;aggregate_gross&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;rank&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;David Yates&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;9.37984e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;James Cameron&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;8.29781e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Carlos Saldanha&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.69293e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Pete Docter&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.31305e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;4&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;4&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Andrew Stanton&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.00319e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;5&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Then, a new column is added that contains the director’s name for the top 9 ranked directors and “All Others” for the remaining directors. This can be accomplished using the Altair &lt;a class="reference external" href="https://altair-viz.github.io/user_guide/transform/calculate.html"&gt;Calculate Transform&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_aggregate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;aggregate_gross&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mean(Worldwide_Gross)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;groupby&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Director&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;row_number()&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SortField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;aggregate_gross&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;descending&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;ranked_director&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;datum.rank &amp;lt; 10 ? datum.Director : &amp;#39;All Others&amp;#39;&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transformed_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row_limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head text-right"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-left"&gt;&lt;p&gt;Director&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;aggregate_gross&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;rank&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-left"&gt;&lt;p&gt;ranked_director&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;David Yates&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;9.37984e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;David Yates&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;James Cameron&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;8.29781e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;James Cameron&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Carlos Saldanha&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.69293e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Carlos Saldanha&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Pete Docter&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.31305e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;4&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Pete Docter&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;4&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Andrew Stanton&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.00319e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;5&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Andrew Stanton&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;5&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;David Slade&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;6.88155e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;6&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;David Slade&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;6&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;George Lucas&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;6.73577e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;George Lucas&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;7&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Andrew Adamson&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;6.43134e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;8&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Andrew Adamson&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;8&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Peter Jackson&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;5.95566e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;9&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Peter Jackson&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;9&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Richard Marquand&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;5.727e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;10&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;All Others&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;10&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Eric Darnell&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;5.66099e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;11&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;All Others&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;11&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Roland Emmerich&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;4.5506e+08&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;12&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;All Others&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Finally, this dataset is ready to be encoded as a bar mark:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;

&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;https://cdn.jsdelivr.net/npm/vega-datasets@v1.29.0/data/movies.json&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_aggregate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;aggregate_gross&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mean(Worldwide_Gross)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;groupby&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Director&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;row_number()&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SortField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;aggregate_gross&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;descending&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;ranked_director&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;datum.rank &amp;lt; 10 ? datum.Director : &amp;#39;All Others&amp;#39;&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;aggregate_gross:Q&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;aggregate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mean&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s2"&gt;&amp;quot;ranked_director:N&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mean&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;aggregate_gross&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;descending&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="Top-K directors" src="https://user-images.githubusercontent.com/15064365/209851553-b6af2a14-affe-4a54-ba17-2590bdbc957d.png" /&gt;&lt;/p&gt;
&lt;p&gt;The exact value of each bar can be accessed by applying &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transformed_data()&lt;/span&gt;&lt;/code&gt; to the final chart (which includes the implicit transforms in the bar mark encoding).&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transformed_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="pst-scrollable-table-container"&gt;&lt;table class="table"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head text-right"&gt;&lt;p&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-left"&gt;&lt;p&gt;ranked_director&lt;/p&gt;&lt;/th&gt;
&lt;th class="head text-right"&gt;&lt;p&gt;mean_aggregate_gross&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;David Yates&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;9.37984e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;James Cameron&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;8.29781e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Carlos Saldanha&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.69293e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Pete Docter&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.31305e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;4&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Andrew Stanton&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;7.00319e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;5&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;David Slade&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;6.88155e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;6&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;George Lucas&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;6.73577e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;7&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Andrew Adamson&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;6.43134e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td class="text-right"&gt;&lt;p&gt;8&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;Peter Jackson&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;5.95566e+08&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td class="text-right"&gt;&lt;p&gt;9&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-left"&gt;&lt;p&gt;All Others&lt;/p&gt;&lt;/td&gt;
&lt;td class="text-right"&gt;&lt;p&gt;8.87602e+07&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="increased-transform-coverage"&gt;
&lt;h2&gt;Increased transform coverage&lt;/h2&gt;
&lt;p&gt;VegaFusion’s coverage of Vega-Lite’s transforms is not yet complete, but it’s growing with each release. Support for the &lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/pivot.html"&gt;Pivot&lt;/a&gt;, &lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/impute.html"&gt;Impute&lt;/a&gt;, &lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/fold.html"&gt;Fold&lt;/a&gt;, and &lt;a class="reference external" href="https://vega.github.io/vega/docs/transforms/sequence/"&gt;Sequence&lt;/a&gt; transforms was added in this release. Here is the full set of supported Vega-Lite/Vega transforms:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/aggregate.html"&gt;Aggregate&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/bin.html"&gt;Bin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/calculate.html"&gt;Calculate&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega/docs/transforms/collect/"&gt;Collect&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega/docs/transforms/extent/"&gt;Extent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/filter.html"&gt;Filter&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/fold.html"&gt;Fold&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega/docs/transforms/identifier/"&gt;Identifier&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/impute.html"&gt;Impute&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/joinaggregate.html"&gt;Join Aggregate&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/pivot.html"&gt;Pivot&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega/docs/transforms/project/"&gt;Project&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega/docs/transforms/sequence/"&gt;Sequence&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/stack.html"&gt;Stack&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/timeunit.html"&gt;Time Unit&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vega.github.io/vega-lite/docs/window.html"&gt;Window&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More on the way!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="leveraging-vlconvert"&gt;
&lt;h2&gt;Leveraging VlConvert&lt;/h2&gt;
&lt;p&gt;Both the new mime renderer and the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transfomed_data()&lt;/span&gt;&lt;/code&gt; function require the ability to convert Vega-Lite specifications (as produced by Altair) to Vega specifications (as consumed by VegaFusion). This functionality is provided by the Vega-Lite JavaScript library, which presents a challenge: How can we perform this conversion in Python without a web browser?&lt;/p&gt;
&lt;p&gt;To meet this challenge, we developed a new Python library called &lt;a class="reference external" href="https://github.com/vega/vl-convert"&gt;VlConvert&lt;/a&gt;.  You can read all about VlConvert in its &lt;a class="reference external" href="https://medium.com/&amp;#64;jonmmease/introducing-vlconvert-c763f0076e89"&gt;announcement post&lt;/a&gt;, but in short it embeds the &lt;a class="reference external" href="https://deno.land/"&gt;Deno&lt;/a&gt; JavaScript runtime in a Python library for the purpose of running the Vega-Lite JavaScript library.&lt;/p&gt;
&lt;p&gt;While motivated by the needs of VegaFusion, VlConvert turned out to be a great foundation for implementing static image export, as it is a simple Python package that doesn’t require external dependencies on a web browser or Node.js.  In fact, VlConvert has been adopted by the Vega community and will be the default image export engine for the coming release of Altair 5!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="a-new-partnership-and-a-new-license"&gt;
&lt;h2&gt;A new partnership and a new license&lt;/h2&gt;
&lt;p&gt;VegaFusion was first released in January 2022 under the copyleft AGPL license. I chose to use the AGPL license initially because I wanted to share the work with the Vega community, but I also wanted to leave open the possibility of building a company with a dual-license business model around the project.&lt;/p&gt;
&lt;p&gt;The day of the initial release, Barry McCardel (the CEO of &lt;a class="reference external" href="https://hex.tech/"&gt;Hex Technologies&lt;/a&gt;) reached out to me, and we started talking about how VegaFusion could help scale the &lt;a class="reference external" href="https://learn.hex.tech/docs/logic-cell-types/display-cells/chart-cells"&gt;Hex chart cell&lt;/a&gt; (which is itself built on Vega-Lite). I granted them a commercial license exception, and started working with the Hex team to integrate VegaFusion into Hex.  After months of working together with Barry and the Hex team, and lots of conversations around the future of the project, we decided that the best path forward was for me to continue working on VegaFusion as a member of Hex team, and for VegaFusion to be re-licensed to a permissive license that is compatible with the rest of the Vega ecosystem.&lt;/p&gt;
&lt;p&gt;The end result is that VegaFusion 1.0 is licensed under the &lt;a class="reference external" href="https://opensource.org/licenses/BSD-3-Clause"&gt;BSD-3&lt;/a&gt; license. Also, to make it easier to take advantage of Hex’s testing infrastructure the VegaFusion repositories have been moved under the &lt;a class="reference external" href="https://github.com/hex-inc"&gt;hex-inc&lt;/a&gt; GitHub organization.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="learn-more"&gt;
&lt;h2&gt;Learn more&lt;/h2&gt;
&lt;p&gt;Check out these resources if you’d like to learn more:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://vegafusion.io/"&gt;VegaFusion Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion"&gt;VegaFusion GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/issues"&gt;Report and Issue&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/discussions"&gt;Start a Discussions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://vegafusion.io/posts/2023/2023-01-21_Release_1.0.0.html"/>
    <summary>Mime renderer, transform evaluation, and a permissive license</summary>
    <published>2023-01-21T00:00:00-05:00</published>
  </entry>
  <entry>
    <id>https://vegafusion.io/posts/2022/2022-01-27_ProjectAnnouncement.html</id>
    <title>VegaFusion 0.1</title>
    <updated>2022-01-27T00:00:00-05:00</updated>
    <author>
      <name>Jon Mease</name>
    </author>
    <content type="html">&lt;section id="vegafusion-0-1"&gt;

&lt;p&gt;&lt;strong&gt;Server-side acceleration for the Vega visualization grammar with Rust and WebAssembly&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By: Jon Mease&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;Today, I’m happy to announce a new open source project I’ve been working on since stepping down as Plotly’s Chief Scientist this past fall. It’s called VegaFusion.&lt;/p&gt;
&lt;p&gt;VegaFusion provides server-side acceleration for the &lt;a class="reference external" href="https://vega.github.io/"&gt;Vega&lt;/a&gt; visualization grammar. While not limited to Python, the initial application of VegaFusion is the acceleration of the &lt;a class="reference external" href="https://altair-viz.github.io/"&gt;Altair&lt;/a&gt; Python interface to &lt;a class="reference external" href="https://vega.github.io/vega-lite/"&gt;Vega-Lite&lt;/a&gt;. Its design was motivated by years of experience working on visualization libraries (&lt;a class="reference external" href="https://plotly.com/python/"&gt;Plotly&lt;/a&gt;, &lt;a class="reference external" href="https://holoviews.org/"&gt;HoloViews&lt;/a&gt;, and &lt;a class="reference external" href="https://datashader.org/"&gt;Datashader&lt;/a&gt;) and dashboard technologies (&lt;a class="reference external" href="https://dash.plotly.com/"&gt;Dash&lt;/a&gt;, &lt;a class="reference external" href="https://ipywidgets.readthedocs.io/en/latest/index.html"&gt;Jupyter Widgets&lt;/a&gt;, and &lt;a class="reference external" href="https://panel.holoviz.org/"&gt;Panel&lt;/a&gt;).&lt;/p&gt;
&lt;section id="quickstart-accelerate-altair-in-jupyter"&gt;
&lt;h2&gt;Quickstart: Accelerate Altair in Jupyter&lt;/h2&gt;
&lt;p&gt;VegaFusion can be used to provide server-side acceleration for Altair visualizations when displayed in Jupyter contexts (Classic notebook, JupyterLab, and Voila).  It also eliminates the Altair &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;MaxRowsError&lt;/span&gt;&lt;/code&gt; when generating a chart with over 5000 rows.&lt;/p&gt;
&lt;p&gt;First, install the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion-jupyter&lt;/span&gt;&lt;/code&gt; package, along with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vega-datasets&lt;/span&gt;&lt;/code&gt; for the example below.&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;vegafusion-jupyter[embed]&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;vega-datasets
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then, open a Jupyter notebook (either the classic notebook, or a notebook inside JupyterLab), and run these two lines to import and enable the VegaFusion Altair renderer.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;vegafusion&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;vf&lt;/span&gt;
&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jupyter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;VegaFusion will now be used to accelerate any Altair chart. For example, here’s the &lt;a class="reference external" href="https://altair-viz.github.io/gallery/selection_layer_bar_month.html"&gt;interactive average&lt;/a&gt; Altair gallery example.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;altair&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;alt&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;vega_datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;

&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seattle_weather&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;brush&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;interval&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encodings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;x&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;bars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;month(date):O&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mean(precipitation):Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;opacity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;brush&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpacityValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpacityValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_selection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;brush&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_rule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;firebrick&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mean(precipitation):Q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SizeValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;brush&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chart&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;video width="600" controls&gt;
  &lt;source src="https://user-images.githubusercontent.com/15064365/148408648-43a5cfd0-b0d8-456e-a77a-dd344d8d07df.mov" type="video/mp4"&gt;
This browser does not support the video tag.
&lt;/video&gt;
&lt;p&gt;Histogram binning, aggregation, selection filtering, and average calculations will now be evaluated in the Python kernel process with efficient parallelization, rather than in the single-threaded browser context.&lt;/p&gt;
&lt;p&gt;You can see that VegaFusion acceleration is working by noticing that the Python &lt;a class="reference external" href="https://experienceleague.adobe.com/docs/experience-platform/data-science-workspace/jupyterlab/overview.html?lang=en#kernel-sessions"&gt;kernel is running&lt;/a&gt; as the selection region is created or moved. You can also notice the VegaFusion logo in the dropdown menu button.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="vega-ecosystem-background"&gt;
&lt;h2&gt;Vega Ecosystem Background&lt;/h2&gt;
&lt;p&gt;VegaFusion is designed to complement the Vega visualization ecosystem. In particular, the &lt;a class="reference external" href="https://vega.github.io/"&gt;Vega&lt;/a&gt;, &lt;a class="reference external" href="https://vega.github.io/vega-lite/"&gt;Vega-Lite&lt;/a&gt;, and &lt;a class="reference external" href="https://altair-viz.github.io/"&gt;Altair&lt;/a&gt; projects.  If you’re not familiar with these projects, it will be helpful to take a few minutes to browse their documentation as background for understanding what VegaFusion adds.&lt;/p&gt;
&lt;section id="transforms-and-signals"&gt;
&lt;h3&gt;Transforms and Signals&lt;/h3&gt;
&lt;p&gt;One powerful feature of the Vega visualization grammar is that it includes a rich collection of data manipulation functions called &lt;a class="reference external" href="https://vega.github.io/vega/docs/transforms/"&gt;transforms&lt;/a&gt;.  Transforms have functionality that is similar to that provided by SQL queries or Pandas DataFrame operations, but they are specifically designed to cover data preprocessing tasks that are useful in constructing data visualizations.&lt;/p&gt;
&lt;p&gt;For additional flexibility, Vega also provides the concept of &lt;a class="reference external" href="https://vega.github.io/vega/docs/signals/"&gt;signals&lt;/a&gt;. These are scalar variables that can be constructed using the &lt;a class="reference external" href="https://vega.github.io/vega/docs/expressions/"&gt;Vega expression language&lt;/a&gt;, which is a subset of JavaScript.  Transforms can accept and produce signals.&lt;/p&gt;
&lt;p&gt;There are at least two significant advantages to having data transformations and signals included in a visualization specification.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;First, it makes it possible for a visualization to accept raw data files as input and then perform its own data cleaning and manipulation.  This often removes the need to generate temporary intermediary data files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Second, it enables higher-level libraries like Vega-Lite to automate the creation of rich interactive visualizations with features like &lt;a class="reference external" href="https://vega.github.io/vega-lite/examples/interactive_layered_crossfilter.html"&gt;cross filtering&lt;/a&gt; and &lt;a class="reference external" href="https://altair-viz.github.io/gallery/select_detail.html"&gt;drill down&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="motivation-for-vegafusion"&gt;
&lt;h2&gt;Motivation for VegaFusion&lt;/h2&gt;
&lt;p&gt;Vega makes it possible to create declarative JSON specifications of rich interactive visualizations that are fully self-contained. They can run entirely in a web browser without requiring access to an external database or a Python library like Pandas.&lt;/p&gt;
&lt;p&gt;For datasets of a few tens of thousands rows or fewer, this architecture often results in extremely smooth and responsive interactivity. However, this architecture doesn’t scale very well to datasets of hundreds of thousands of rows or more.  This is the gap VegaFusion aims to fill.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="how-vegafusion-works"&gt;
&lt;h2&gt;How VegaFusion Works&lt;/h2&gt;
&lt;p&gt;VegaFusion has two primary components: The Planner and the Runtime.&lt;/p&gt;
&lt;section id="planner"&gt;
&lt;h3&gt;Planner&lt;/h3&gt;
&lt;p&gt;The Planner starts with an arbitrary Vega specification (typically generated by Vega-Lite, but this is not a requirement). The Planner’s job is to partition the specification into two valid Vega specifications, one that will execute in the browser with the Vega JavaScript library, and one that will execute on the server with the VegaFusion Runtime.&lt;/p&gt;
&lt;p&gt;VegaFusion does not (yet) provide full coverage of all of Vega’s transforms and all of the features of the Vega expression language.  The planner uses information about which transforms and expression functions are supported to make decisions about which parts of the original Vega specification can be included in the resulting server specification.  The advantage of this approach is that VegaFusion can accept any Vega specification, and as more support is added over time, more of the input specification will be eligible for inclusion in the server specification.&lt;/p&gt;
&lt;p&gt;Along with the client and server specifications, the planner also creates a communication plan.  The communication plan determines which datasets and signals must be passed from server to client, and from client to server in order for the interactive behavior of the original specification to be preserved.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="runtime"&gt;
&lt;h3&gt;Runtime&lt;/h3&gt;
&lt;p&gt;After planning, the server specification is compiled into a VegaFusion task graph.  The job of the Runtime is to calculate the value of requested nodes within a task graph.&lt;/p&gt;
&lt;p&gt;A task graph includes the values of the root nodes (those with no parents), but it does not include the values of any of the interior nodes (those with parents).  Each node in the task graph is a pure function of the values of its parents.  This enables the Runtime to calculate the value of any node in the Task graph from the specification, while keeping the overall task graph size small enough to be efficiently transferred between the client and the server.  The Runtime uses fingerprinting and precise caching to avoid repeated calculations of the same nodes.  The cache is “precise” in the sense that cached values can be shared across visualizations that share a common substructure, even if the full specifications are not identical.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="technology"&gt;
&lt;h2&gt;Technology&lt;/h2&gt;
&lt;section id="vegafusion-technology-stack"&gt;
&lt;h3&gt;VegaFusion Technology Stack&lt;/h3&gt;
&lt;p&gt;VegaFusion uses a fairly diverse technology stack. The Planner and Runtime are both implemented in Rust.&lt;/p&gt;
&lt;p&gt;In the context of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion-jupyter&lt;/span&gt;&lt;/code&gt;, the Planner is compiled to WebAssembly using &lt;a class="reference external" href="https://github.com/rustwasm/wasm-pack"&gt;wasm-pack&lt;/a&gt; and wrapped in a TypeScript API using &lt;a class="reference external" href="https://github.com/rustwasm/wasm-bindgen"&gt;wasm-bindgen&lt;/a&gt;.  This TypeScript API is used to integrate the WebAssembly library into the VegaFusion Jupyter Widget.&lt;/p&gt;
&lt;p&gt;The Runtime is wrapped in a Python API using &lt;a class="reference external" href="https://github.com/PyO3/pyo3"&gt;PyO3&lt;/a&gt;, resulting in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion-python&lt;/span&gt;&lt;/code&gt; package.  The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion-jupyter&lt;/span&gt;&lt;/code&gt; package is used to integrate &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vegafusion-python&lt;/span&gt;&lt;/code&gt; with Altair and the Python portion of VegaFusion Jupyter Widget.&lt;/p&gt;
&lt;p&gt;The Task Graph specifications are defined as protocol buffer messages. The &lt;a class="reference external" href="https://github.com/tokio-rs/prost"&gt;prost&lt;/a&gt; library is used to generate Rust data structures from these protocol buffer messages.  When Arrow tables appear as task graph root values, they are serialized inside the protocol buffer specification using the &lt;a class="reference external" href="https://arrow.apache.org/docs/format/Columnar.html#serialization-and-interprocess-communication-ipc"&gt;Apache Arrow IPC format&lt;/a&gt;.  The binary representation of the task graph protocol buffer message is what is transferred across the Jupyter Comms protocol.&lt;/p&gt;
&lt;img width="749" alt="VegaFusion Jupyter Architecture Diagram" src="https://user-images.githubusercontent.com/15064365/148417030-19420ef2-50de-40cf-bd42-c39e1147049c.png"&gt;
&lt;/section&gt;
&lt;section id="datafusion-integration"&gt;
&lt;h3&gt;DataFusion integration&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/apache/arrow-datafusion"&gt;Apache Arrow DataFusion&lt;/a&gt; is an SQL compatible query engine that integrates with the Rust implementation of Apache Arrow.  VegaFusion uses DataFusion to implement many of the Vega transforms, and it compiles the Vega expression language directly into the DataFusion expression language.  In addition to being really fast, a particularly powerful characteristic of DataFusion is that it provides many interfaces that can be extended with custom Rust logic.  For example, VegaFusion defines many custom UDFs that are designed to implement the precise semantics of the Vega expression language and the Vega expression functions.&lt;/p&gt;
&lt;img width="200" alt="DataFusion Logo" src="https://github.com/apache/arrow-datafusion/raw/master/docs/source/_static/images/DataFusion-Logo-Background-White.svg"&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="examples"&gt;
&lt;h2&gt;Examples&lt;/h2&gt;
&lt;p&gt;VegaFusion is compatible with all of the examples in the &lt;a class="reference external" href="https://altair-viz.github.io/gallery/index.html"&gt;Altair gallery&lt;/a&gt;. Here are a few additional examples that demonstrate the benefits of server-side acceleration.&lt;/p&gt;
&lt;section id="large-altair-gallery-examples"&gt;
&lt;h3&gt;Large Altair Gallery Examples&lt;/h3&gt;
&lt;p&gt;The following examples are modifications of Altair Gallery examples that use larger datasets.  Each example displays the same plot with plain Altair and with Altair + VegaFusion to make is easy to compare performance.  You can try them out using the binder links below.&lt;/p&gt;
&lt;section id="interactive-crossfilter"&gt;
&lt;h4&gt;Interactive Crossfilter&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/vegafusion/demos/blob/main/notebooks/large_altair_examples/flights_crossfilter.ipynb"&gt;Notebook file&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://mybinder.org/v2/gh/vegafusion/demos/HEAD?urlpath=voila%2Frender%2Fnotebooks%2Flarge_altair_examples%2Fflights_crossfilter.ipynb"&gt;&lt;img alt="Binder" src="https://mybinder.org/badge_logo.svg" /&gt;&lt;/a&gt; - Voila Dashboard&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://gesis.mybinder.org/binder/v2/gh/vegafusion/demos/93a9a68100de0d6282b114f8cf01cbb30c672267?urlpath=lab%2Ftree%2Fnotebooks%2Flarge_altair_examples%2Fflights_crossfilter.ipynb"&gt;&lt;img alt="Binder" src="https://mybinder.org/badge_logo.svg" /&gt;&lt;/a&gt; - Jupyterlab&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;video controls&gt;
  &lt;source src="https://user-images.githubusercontent.com/15064365/150031835-5b5b4294-eb88-47db-bbcc-91e89708ce40.mov" type="video/mp4"&gt;
This browser does not support the video tag.
&lt;/video&gt;
&lt;/section&gt;
&lt;section id="interactive-average"&gt;
&lt;h4&gt;Interactive Average&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/vegafusion/demos/blob/main/notebooks/large_altair_examples/interactive_average.ipynb"&gt;Notebook file&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://mybinder.org/v2/gh/vegafusion/demos/HEAD?urlpath=voila%2Frender%2Fnotebooks%2Flarge_altair_examples%2Finteractive_average.ipynb"&gt;&lt;img alt="Binder" src="https://mybinder.org/badge_logo.svg" /&gt;&lt;/a&gt; - Voila Dashboard&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://gesis.mybinder.org/binder/v2/gh/vegafusion/demos/93a9a68100de0d6282b114f8cf01cbb30c672267?urlpath=lab%2Ftree%2Fnotebooks%2Flarge_altair_examples%2Finteractive_average.ipynb"&gt;&lt;img alt="Binder" src="https://mybinder.org/badge_logo.svg" /&gt;&lt;/a&gt; - JupyterLab&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;video controls&gt;
  &lt;source src="https://user-images.githubusercontent.com/15064365/150031863-3d877f08-2f9a-41a3-8cbb-95bc52f8b206.mov" type="video/mp4"&gt;
This browser does not suppor class="video-border"t the video tag.
&lt;/video&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="million-taxi-rides"&gt;
&lt;h3&gt;10 Million Taxi Rides&lt;/h3&gt;
&lt;p&gt;This example creates a dashboard to explore 10 million taxi rides in New York City from January 2015.  It supports zoom-based rasterization of the pickup locations (similar to &lt;a class="reference external" href="https://datashader.org/"&gt;Datashader&lt;/a&gt;), and combines that with cross filtering across a histogram of trip distances and a heatmap of tip rate by hour and day of the week.&lt;/p&gt;
&lt;p&gt;See the &lt;a class="reference external" href="https://examples.pyviz.org/nyc_taxi/nyc_taxi.html"&gt;PyViz documentation example&lt;/a&gt; for more information on the dataset.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/vegafusion/demos/blob/main/notebooks/nyc_taxi/nyc_taxi.ipynb"&gt;Notebook file&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;video controls&gt;
  &lt;source src="https://vegafusion-datasets.s3.amazonaws.com/screencasts/10MillionTaxiRides.mov" type="video/mp4"&gt;
This browser does not support the video tag.
&lt;/video&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="about-the-name"&gt;
&lt;h2&gt;About the Name&lt;/h2&gt;
&lt;p&gt;There are two meanings behind the name “VegaFusion”&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;It’s a reference to the &lt;a class="reference external" href="https://github.com/apache/arrow-datafusion"&gt;Apache Arrow DataFusion&lt;/a&gt; library described above&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vega and Altair are named after stars, and stars are powered by nuclear fusion&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="licensing-and-funding"&gt;
&lt;h2&gt;Licensing and Funding&lt;/h2&gt;
&lt;p&gt;At least until a sustainable funding model is established, VegaFusion will be developed under the &lt;a class="reference external" href="https://www.gnu.org/licenses/agpl-3.0.en.html"&gt;AGPLv3 license&lt;/a&gt;.  This is a copy-left license in the GPL family of licenses. As with all &lt;a class="reference external" href="https://opensource.org/licenses/alphabetical"&gt;OSI approved licenses&lt;/a&gt;, there are no restrictions on what code licensed under the AGPL can be used for. However, the requirements for what must be shared publicly are greater than for licenses that are more commonly used in the Python ecosystem like &lt;a class="reference external" href="https://opensource.org/licenses/Apache-2.0"&gt;Apache-2&lt;/a&gt;, &lt;a class="reference external" href="https://opensource.org/licenses/MIT"&gt;MIT&lt;/a&gt;, and &lt;a class="reference external" href="https://opensource.org/licenses/BSD-3-Clause"&gt;BSD-3&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="roadmap"&gt;
&lt;h2&gt;Roadmap&lt;/h2&gt;
&lt;p&gt;This is only the beginning for VegaFusion. There are a lot of possible future directions, and many of them are detailed in the roadmap.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="learn-more"&gt;
&lt;h2&gt;Learn more&lt;/h2&gt;
&lt;p&gt;Here are some ways that you can get in touch to learn more.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Check out the code on &lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/"&gt;GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start a discussion on &lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/discussions"&gt;GitHub Discussions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And of course, if something doesn’t work please &lt;a class="reference external" href="https://github.com/hex-inc/vegafusion/issues"&gt;open an issue&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks!&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://vegafusion.io/posts/2022/2022-01-27_ProjectAnnouncement.html"/>
    <summary>Server-side acceleration for the Vega visualization grammar with Rust and WebAssembly</summary>
    <published>2022-01-27T00:00:00-05:00</published>
  </entry>
  <entry>
    <id>https://vegafusion.io/posts/2022/2022-01-19_Release_0.0.1.html</id>
    <title>VegaFusion 0.0.1</title>
    <updated>2022-01-19T00:00:00-05:00</updated>
    <author>
      <name>Jon Mease</name>
    </author>
    <content type="html">&lt;section id="vegafusion-0-0-1"&gt;

&lt;p&gt;The first public version of VegaFusion has been released as 0.0.1.  Full project announcement to follow!&lt;/p&gt;
&lt;/section&gt;
</content>
    <link href="https://vegafusion.io/posts/2022/2022-01-19_Release_0.0.1.html"/>
    <summary>The first public version of VegaFusion has been released as 0.0.1.  Full project announcement to follow!</summary>
    <published>2022-01-19T00:00:00-05:00</published>
  </entry>
</feed>
