<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Jupyter Blog - Madhur Tandon</title><link href="https://jasongrout.github.io/medium-archive/pelican/" rel="alternate"/><link href="https://jasongrout.github.io/medium-archive/pelican/feeds/author-madhur-tandon.atom.xml" rel="self"/><id>https://jasongrout.github.io/medium-archive/pelican/</id><updated>2020-12-03T14:23:00+00:00</updated><subtitle>The Project Jupyter blog: news, releases, and community stories, archived from blog.jupyter.org.</subtitle><entry><title>A C++ API for Vega-Lite</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/" rel="alternate"/><published>2020-12-02T15:27:00+00:00</published><updated>2020-12-03T14:23:00+00:00</updated><author><name>Madhur Tandon</name></author><id>tag:jasongrout.github.io,2020-12-02:/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/</id><summary type="html">&lt;p&gt;In this post, we present the first public release of XVega, a C++ library for producing vega-lite charts.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;em&gt;In this post, we present the first public release of XVega, a C++ library for producing Vega-Lite charts.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Data science workflows differ from traditional software development in that engineers make use of available tools to &lt;em&gt;explore&lt;/em&gt; and &lt;em&gt;reason&lt;/em&gt; about a problem. In such exploratory work, engineers load data, crunch numbers, produce simple visualizations and &lt;em&gt;iterate…&lt;/em&gt; Progress happens in quick incremental iterations, which is possible when tooling does not get in the way.&lt;/p&gt;
&lt;p&gt;This kind of interactive computing is generally associated with the Python or R programming languages. However, with the advent of the &lt;a href="https://github.com/root-project/cling/"&gt;&lt;strong&gt;Cling&lt;/strong&gt;&lt;/a&gt; C++ interpreter from &lt;a href="https://home.cern/"&gt;CERN&lt;/a&gt;, and the subsequent development of the &lt;a href="https://github.com/jupyter-xeus/xeus-cling"&gt;&lt;strong&gt;xeus-cling&lt;/strong&gt;&lt;/a&gt; Jupyter kernel, new possibilities have opened up in this space.&lt;/p&gt;
&lt;p&gt;The Jupyter stack — that started in the scientific Python community has evolved into a language-agnostic framework that can now be leveraged by C++ developers. It bridges the gap between the countless scientific computing libraries and tools available in C++ and the Jupyter ecosystem.&lt;/p&gt;
&lt;p&gt;The scientific C++ stack now has numerous projects under its belt — such as &lt;a href="https://github.com/xtensor-stack/xtensor"&gt;xtensor&lt;/a&gt;, &lt;a href="https://github.com/xtensor-stack/xframe"&gt;xframe&lt;/a&gt;, etc. However, there is little support for visualization — especially for interactive plots. While there exist &lt;a href="https://github.com/lava/matplotlib-cpp"&gt;matplotlib-cpp&lt;/a&gt; and &lt;a href="https://github.com/alandefreitas/matplotplusplus"&gt;matplotplusplus&lt;/a&gt; (with their plotting API resembling the original &lt;a href="https://github.com/matplotlib/matplotlib"&gt;matplotlib&lt;/a&gt; library) — they suffer from the same cons as the original library does (such as the imperative API and the confusion between dual object-oriented and state-based interface).&lt;/p&gt;
&lt;p&gt;Owing to all these shortcomings, along with the observation that JupyterLab comes with existing support for Vega and Vega-Lite Charts (through the &lt;a href="https://jupyterlab.readthedocs.io/en/stable/user/file_formats.html#vega-vega-lite"&gt;&lt;code&gt;application/vnd.vegalite.v3+json&lt;/code&gt;&lt;/a&gt; MIME type), one can leverage this support to bridge the gap rather than reinvent the wheel. Apart from standalone use — one could also integrate such a system into other projects such as &lt;a href="https://github.com/jupyter-xeus/xeus-sqlite"&gt;xeus-SQLite&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The main idea is to programmatically fill in a JSON that conforms to the Vega-Lite specification and respects the notion of grammar of graphics. It is analogous to what &lt;a href="https://github.com/altair-viz/altair"&gt;Altair&lt;/a&gt; did for Python. We will expose different APIs responsible for filling in certain parts of the JSON.&lt;/p&gt;
&lt;p&gt;The fundamentals with XVega are still the same, i.e. the three essential elements of a &lt;em&gt;Chart&lt;/em&gt; are &lt;em&gt;Data, Marks and Encodings&lt;/em&gt; as usual and importing the library is as simple as writing two statements:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;xvega/xvega.hpp&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;xv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The experience is similar to what Altair offers and, hence, the central piece to the library is the &lt;em&gt;&lt;strong&gt;Chart()&lt;/strong&gt;&lt;/em&gt; object — which knows how to emit the JSON dictionary representing the data and visualization encodings.&lt;/p&gt;
&lt;p&gt;For those unfamiliar with the Vega ecosystem, a quick recap for the above terms is given below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Marks&lt;/strong&gt;&lt;/em&gt; — What graphic should represent the data?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Encodings&lt;/strong&gt;&lt;/em&gt; — Mapping between Data and Visual Elements of the Chart (such as x-axis, etc.).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Encoding Types&lt;/strong&gt;&lt;/em&gt;: &lt;em&gt;&lt;strong&gt;Quantitative&lt;/strong&gt;&lt;/em&gt; (real-valued), &lt;em&gt;&lt;strong&gt;Nominal&lt;/strong&gt;&lt;/em&gt; (unordered categorical), &lt;em&gt;&lt;strong&gt;Ordinal&lt;/strong&gt;&lt;/em&gt; (ordered categorical), &lt;em&gt;&lt;strong&gt;Temporal&lt;/strong&gt;&lt;/em&gt; (time-series).&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="Basic usage of XVega showcasing the essential elements — Data, Marks and Encodings." src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/001-1_GCkpVPeF-s7-64hNzyOcjg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Basic usage of XVega showcasing the essential elements — Data, Marks and Encodings.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The core strength of using such a system is the separation of specification and execution. The declarative API makes it easy to specify “&lt;em&gt;&lt;strong&gt;what&lt;/strong&gt;&lt;/em&gt;” should be done rather than focus on incidental details of the “&lt;em&gt;&lt;strong&gt;how&lt;/strong&gt;&lt;/em&gt;”. It means that rather than having a special “&lt;em&gt;&lt;strong&gt;hist()&lt;/strong&gt;&lt;/em&gt;” function for plotting a histogram, passing “&lt;em&gt;&lt;strong&gt;bin=True&lt;/strong&gt;&lt;/em&gt;” does the job.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Simply stating bin=True bins the x-axis giving us the Histogram directly — without using a dedicated function." src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/002-1_t3w0G2XCiNBw3VajHbGiCw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Simply stating &lt;strong&gt;bin=True&lt;/strong&gt; bins the x-axis giving us the Histogram directly — without using a dedicated function.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We can of-course customize the binning parameters with a “&lt;em&gt;&lt;strong&gt;Bin()&lt;/strong&gt;&lt;/em&gt;” object instead. And while we are doing that, let’s add a colour encoding as well to get a sense of the 3rd dimension.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="More control can be achieved using a custom Bin() object — used to set the binning parameters." src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/003-1_UkIPGquufhYT7-S62MTECg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;More control can be achieved using a custom &lt;strong&gt;Bin()&lt;/strong&gt; object — used to set the binning parameters.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Another plus of using Vega-Lite is the possibility of using transformations within the specification rather than doing it before.&lt;br&gt;
(E.g., one can do linear regression as a part of this declarative API).&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Usage of layering and transformations in XVega." src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/004-1_2jpd8rcTdgnLq8fBwL0XXA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Usage of layering and transformations in XVega.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Lastly, support for &lt;em&gt;&lt;strong&gt;Interactions&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;Selections&lt;/strong&gt;&lt;/em&gt; is a no-brainer. It’s as simple as defining what to use and adding it to the &lt;em&gt;&lt;strong&gt;Chart()&lt;/strong&gt;&lt;/em&gt; object.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Zooming and Panning along with Tooltips using Interval Selection in XVega" src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/005-1_AQTFHOwHXS3uJUC6WKR6WA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Zooming and Panning along with Tooltips using Interval Selection in XVega&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;hr&gt;
&lt;p&gt;Developing such a system for C++ comes with its own challenges and to provide a seamless experience like &lt;em&gt;Altair&lt;/em&gt;, several things are needed to be taken care of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multiple types for a single entity:&lt;/strong&gt; the Vega-Lite specification allows variables of different kinds (such as a boolean type and an integer type may be equally valid for a particular property). &lt;em&gt;&lt;strong&gt;Variants&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;Visitors&lt;/strong&gt;&lt;/em&gt; in C++ allow us to achieve this.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Out of order keyword arguments:&lt;/strong&gt; Method chaining is the classical approach to tackle out-of-order keyword arguments in C++ and is what is used in &lt;em&gt;&lt;strong&gt;XVega&lt;/strong&gt;&lt;/em&gt; indeed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optional fields:&lt;/strong&gt; A lot of values in the Vega-Lite specification are optional, and this is made possible by the optionally contained values in C++ (i.e. using &lt;em&gt;std::optional&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="installation"&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;You can install XVega with conda or &lt;a href="https://github.com/mamba-org/mamba"&gt;mamba&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mamba install -c conda-forge xvega
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda install -c conda-forge xvega
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h3 id="what-is-coming"&gt;What is coming?&lt;/h3&gt;
&lt;p&gt;XVega is still at an early stage and under active development. We are currently working on integrating it with the &lt;a href="https://github.com/jupyter-xeus/xeus-sqlite"&gt;xeus-sqlite&lt;/a&gt; and other SQL Jupyter kernels to enable the visualization from SQL queries. We are also working on improving the compilation time of XVega with Cling.&lt;/p&gt;
&lt;h3 id="acknowledgements"&gt;Acknowledgements&lt;/h3&gt;
&lt;p&gt;This work on XVega was funded by &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;. Thanks to &lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt; and &lt;a href="https://twitter.com/JohanMabille"&gt;Johan Mabille&lt;/a&gt; for their continuous support.&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;It is an exciting time for the interactive C++ ecosystem, as so much innovation is happening in the Cling and Jupyter projects. There is a lot more to come for sure. If you are interested in helping us build that future, come talk to us at &lt;a href="https://gitter.im/QuantStack/Lobby"&gt;Gitter&lt;/a&gt; and &lt;a href="https://github.com/QuantStack/"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id="about-the-author"&gt;About the Author&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-c-backend-for-vega-lite/images/006-1_smY4K4tEKudPztWWxpBNvw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;My name is &lt;a href="https://twitter.com/mad_tandon"&gt;Madhur Tandon&lt;/a&gt;, and I currently work with &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt; as a Scientific Software Engineer. Before joining QuantStack, I have worked with &lt;a href="https://github.com/iodide-project/pyodide"&gt;Mozilla&lt;/a&gt;, &lt;a href="https://www.deepnote.com/"&gt;Deepnote&lt;/a&gt;, &lt;a href="https://github.com/BIDS-Apps/rsHRF"&gt;INCF&lt;/a&gt; (International Neuroinformatics Coordinating Facility), &lt;a href="https://www.tcs.com/tcs-research"&gt;TCS Research&lt;/a&gt; and &lt;a href="https://elucidata.io/"&gt;Elucidata&lt;/a&gt;. I have also been a speaker at JupyterCon 2020 and PyData Delhi 2017 and 2018. I graduated from &lt;a href="https://iiitd.ac.in/"&gt;IIIT-Delhi&lt;/a&gt; this year with a Bachelor’s degree in Computer Science with Honors. Besides core Data Science and Machine Learning, I am interested in tools that enable and enhance data scientists’ workflow and experience.&lt;/p&gt;
</content><category term="C++"/><category term="visualization"/></entry></feed>