{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Compound Charts\n", "\n", "Altair provides a concise API for creating multi-panel and layered charts, and we'll mention three of them explicitly here:\n", "\n", "- Layering\n", "- Horizontal Concatenation\n", "- Vertical Concatenation\n", "- Repeat Charts\n", "\n", "We'll explore those briefly here." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import altair as alt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Layering\n", "\n", "Layering lets you put layer multiple marks on a single Chart. One common example is creating a plot with both points and lines representing the same data.\n", "\n", "Let's use the ``stocks`` data for this example:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
symboldateprice
0MSFT2000-01-0139.81
1MSFT2000-02-0136.35
2MSFT2000-03-0143.22
3MSFT2000-04-0128.37
4MSFT2000-05-0125.45
\n", "
" ], "text/plain": [ " symbol date price\n", "0 MSFT 2000-01-01 39.81\n", "1 MSFT 2000-02-01 36.35\n", "2 MSFT 2000-03-01 43.22\n", "3 MSFT 2000-04-01 28.37\n", "4 MSFT 2000-05-01 25.45" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from vega_datasets import data\n", "stocks = data.stocks()\n", "stocks.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is a simple line plot for the stocks data:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.Chart(...)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "alt.Chart(stocks).mark_line().encode(\n", " x='date:T',\n", " y='price:Q',\n", " color='symbol:N'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and here is the same plot with a ``circle`` mark:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.Chart(...)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "alt.Chart(stocks).mark_circle().encode(\n", " x='date:T',\n", " y='price:Q',\n", " color='symbol:N'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can layer these two plots together using a ``+`` operator:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lines = alt.Chart(stocks).mark_line().encode(\n", " x='date:T',\n", " y='price:Q',\n", " color='symbol:N'\n", ")\n", "\n", "points = alt.Chart(stocks).mark_circle().encode(\n", " x='date:T',\n", " y='price:Q',\n", " color='symbol:N'\n", ")\n", "\n", "lines + points" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This ``+`` is just a shortcut to the ``alt.layer()`` function, which does the same thing:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "alt.layer(lines, points)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One pattern we'll use often is to create a base chart with the common elements, and add together two copies with just a single change:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.LayerChart(...)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "base = alt.Chart(stocks).encode(\n", " x='date:T',\n", " y='price:Q',\n", " color='symbol:N'\n", ")\n", "\n", "base.mark_line() + base.mark_circle()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Horizontal Concatenation\n", "\n", "Just as we can layer charts on top of each other, we can concatenate horizontally using ``alt.hconcat``, or equivalently the ``|`` operator:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.HConcatChart(...)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "base.mark_line() | base.mark_circle()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.HConcatChart(...)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "alt.hconcat(base.mark_line(),\n", " base.mark_circle())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This can be most useful for creating multi-panel views; for example, here is the iris dataset:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sepalLengthsepalWidthpetalLengthpetalWidthspecies
05.13.51.40.2setosa
14.93.01.40.2setosa
24.73.21.30.2setosa
34.63.11.50.2setosa
45.03.61.40.2setosa
\n", "
" ], "text/plain": [ " sepalLength sepalWidth petalLength petalWidth species\n", "0 5.1 3.5 1.4 0.2 setosa\n", "1 4.9 3.0 1.4 0.2 setosa\n", "2 4.7 3.2 1.3 0.2 setosa\n", "3 4.6 3.1 1.5 0.2 setosa\n", "4 5.0 3.6 1.4 0.2 setosa" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "iris = data.iris()\n", "iris.head()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.HConcatChart(...)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "base = alt.Chart(iris).mark_point().encode(\n", " x='petalWidth',\n", " y='petalLength',\n", " color='species'\n", ")\n", "\n", "base | base.encode(x='sepalWidth')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Vertical Concatenation\n", "\n", "Vertical concatenation looks a lot like horizontal concatenation, but using either the ``alt.hconcat()`` function, or the ``&`` operator:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.VConcatChart(...)" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "base & base.encode(y='sepalWidth')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Repeat Chart\n", "\n", "Because it is such a common pattern to horizontally and vertically concatenate charts while changing one encoding, Altair offers a shortcut for this, using the ``repeat()`` operator." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "" ], "text/plain": [ "alt.RepeatChart(...)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import altair as alt\n", "from vega_datasets import data\n", "\n", "iris = data.iris()\n", "\n", "fields = ['petalLength', 'petalWidth', 'sepalLength', 'sepalWidth']\n", "\n", "alt.Chart(iris).mark_point().encode(\n", " alt.X(alt.repeat(\"column\"), type='quantitative'),\n", " alt.Y(alt.repeat(\"row\"), type='quantitative'),\n", " color='species'\n", ").properties(\n", " width=200,\n", " height=200\n", ").repeat(\n", " row=fields,\n", " column=fields[::-1]\n", ").interactive()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This repeat API is still not as streamlined as it could be, but we'll be working on that." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" } }, "nbformat": 4, "nbformat_minor": 4 }