Skip to content

Commit

Permalink
Merge pull request #1113 from kindofluke/binding-documentation
Browse files Browse the repository at this point in the history
Binding documentation
  • Loading branch information
jakevdp authored Aug 29, 2018
2 parents 5913f1a + 91919cc commit 701c656
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 9 deletions.
90 changes: 90 additions & 0 deletions altair/vegalite/v2/examples/multiple_interactions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""
Multiple Interations
====================
This example shows how multiple user inputs can be layered onto a chart. The four inputs have functionality as follows:
* Dropdown: Filters the movies by genre
* Radio Buttons: Highlights certain films by Worldwide Gross
* Mouse Drag and Scroll: Zooms the x and y scales to allow for panning.
"""
# category: interactive charts
import altair as alt
from vega_datasets import data


movies = alt.UrlData(data.movies.url, format=alt.DataFormat(parse={"Release_Date":"date"}))

ratings = ['G', 'NC-17', 'PG', 'PG-13', 'R']

genres = ['Action', 'Adventure', 'Black Comedy', 'Comedy',
'Concert/Performance', 'Documentary', 'Drama', 'Horror', 'Musical',
'Romantic Comedy', 'Thriller/Suspense', 'Western']

base = alt.Chart(movies, width=200, height=200).mark_point(filled=True).transform_calculate(
Rounded_IMDB_Rating = "floor(datum.IMDB_Rating)",
Hundred_Million_Production = "datum.Production_Budget > 100000000.0 ? 100 : 10",
Release_Year = "year(datum.Release_Date)"
).transform_filter(
alt.datum.IMDB_Rating > 0
).transform_filter(
alt.FieldOneOfPredicate(field='MPAA_Rating', oneOf=ratings)
).encode(
x=alt.X('Worldwide_Gross:Q', scale=alt.Scale(domain=(100000,10**9), clamp=True)),
y='IMDB_Rating:Q',
tooltip="Title:N"
)

# A slider filter
year_slider = alt.binding_range(min=1969, max=2018, step=1)
slider_selection = alt.selection_single(bind=year_slider, fields=['Release_Year'], name="Release Year_")


filter_year = base.add_selection(
slider_selection
).transform_filter(
slider_selection
).properties(title="Slider Filtering")

# A dropdown filter
genre_dropdown = alt.binding_select(options=genres)
genre_select = alt.selection_single(fields=['Major_Genre'], bind=genre_dropdown, name="Genre")

filter_genres = base.add_selection(
genre_select
).transform_filter(
genre_select
).properties(title="Dropdown Filtering")

#color changing marks
rating_radio = alt.binding_radio(options=ratings)

rating_select = alt.selection_single(fields=['MPAA_Rating'], bind=rating_radio, name="Rating")
rating_color_condition = alt.condition(rating_select,
alt.Color('MPAA_Rating:N', legend=None),
alt.value('lightgray'))

highlight_ratings = base.add_selection(
rating_select
).encode(
color=rating_color_condition
).properties(title="Radio Button Highlighting")

# Boolean selection for format changes
input_checkbox = alt.binding_checkbox()
checkbox_selection = alt.selection_single(bind=input_checkbox, name="Big Budget Films")

size_checkbox_condition = alt.condition(checkbox_selection,
alt.SizeValue(25),
alt.Size('Hundred_Million_Production:Q')
)

budget_sizing = base.add_selection(
checkbox_selection
).encode(
size=size_checkbox_condition
).properties(title="Checkbox Formatting")

( filter_year | filter_genres) & (highlight_ratings | budget_sizing )
2 changes: 1 addition & 1 deletion doc/case_studies/exploring-weather.rst
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ by weather type:
And now we can vertically concatenate this histogram to the points plot above,
and add a brush selection tool such that the histogram reflects the content
of the selection (for more information on selections, see
:ref:`user-guide-selections`):
:ref:`user-guide-interactions`):

.. altair-plot::

Expand Down
2 changes: 1 addition & 1 deletion doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ beautiful and effective visualizations with a minimal amount of code.
user_guide/encoding
user_guide/marks
user_guide/transform
user_guide/selections
user_guide/interactions
user_guide/configuration
user_guide/compound_charts
user_guide/saving_charts
Expand Down
121 changes: 114 additions & 7 deletions doc/user_guide/selections.rst → doc/user_guide/interactions.rst
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
.. currentmodule:: altair

.. _user-guide-selections:
.. _user-guide-interactions:

Bindings, Selections, Conditions: Making Charts Interactive
===========================================================

Selections: Building Blocks of Interactions
-------------------------------------------
One of the unique features of Altair, inherited from Vega-Lite, is a
declarative grammar of not just visualization, but *interaction*. The
core concept of this grammar is the *selection* object.
declarative grammar of not just visualization, but *interaction*. There are three
core concepts of this grammar:

- the :func:`selection` object which captures interactions from the mouse or through other inputs to effect the chart. Inputs can either be events like moust clicks or drags. Inputs can also be elemnts like a drop-down, radio button or slider. Selections can be used alone but if you want to have change any element of your chart you will need to connect them to a *condition*.
- the :func:`condition` function takes the selection input and changes an element of the chart based on that input.
- the ``bind`` property of a selection which establishes a two-way binding between the selection and an input element of your chart.

Interactive charts can use one or more of these elements to create rich interactivity between the viewer and the data.


Selections: Building Blocks of Interactions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Selections in Altair come in a few flavors, and they can be *bound* to
particular charts or sub-charts in your visualization, then referenced
in other parts of the visualization.

Example: Linked-Brush Scatter-Plot
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

As a motivation, let's create a simple chart and then add some selections
to it. Here is a simple scatter-plot created from the ``cars`` dataset:
Expand Down Expand Up @@ -55,6 +67,9 @@ property:
The result above is a chart that allows you to click and drag to create
a selection region, and to move this region once the region is created.

Conditions: Making the chart respond
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is neat, but the selection doesn't actually *do* anything yet.
To use this selection, we need to reference it in some way within
the chart. Here, we will use the :func:`condition` function to create
Expand Down Expand Up @@ -308,10 +323,102 @@ cylinders:
By fine-tuning the behavior of selections in this way, they can be used to
create a wide variety of linked interactive chart types.

Binding: Adding Data Driven Inputs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With an understanding of the selection types and conditions, you can now add data-driven input elements to the charts using the :class:`bind`. As specified by `Vega-lite binding <https://vega.github.io/vega-lite/docs/bind.html#input-element-binding>`_, selections can be bound two-ways:

1. Single selections can be bound directly to an input elements. *For example, a radio button.*
2. Interval selections which can be bound to scale. *for example, zooming in on a map.*

Input Element Binding
^^^^^^^^^^^^^^^^^^^^^
With single selections, an input element can be added to the chart to establish a binding between the input and the selection.

For instance, using our example from above a dropdown can be used to highlight cars from a specific ``origin`` :

.. altair-plot::

input_dropdown = alt.binding_select(options=['Europe','Japan','USA'])
selection = alt.selection_single(fields=['Origin'], bind=input_dropdown, name='Country of ')
color = alt.condition(selection,
alt.Color('Origin:N', legend=None),
alt.value('lightgray'))

alt.Chart(cars).mark_point().encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color=color,
tooltip='Name:N'
).add_selection(
selection
)




The above example shows all three elements at work. The :input_dropdown: is :bind: to the :selection: which is called from the :condition: encoded through the data.

The following are the input elements supported in vega-lite:


========================= =========================================================================== ===============================================
Input Element Description Example
========================= =========================================================================== ===============================================
:class:`binding_checkbox` Renders as checkboxes allowing for multiple selections of items. :ref:`gallery_multiple_interactions`
:class:`binding_radio` Radio buttons that force only a single selection :ref:`gallery_multiple_interactions`
:class:`binding_select` Drop down box for selecting a single item from a list :ref:`gallery_multiple_interactions`
:class:`binding_range` Shown as a slider to allow for selection along a scale. :ref:`gallery_us_population_over_time`
========================= =========================================================================== ===============================================


Bindings and input elements can also be used to filter data on the client side. Reducing noise in the chart and allowing the user to see just certain selected elements:

.. altair-plot::

input_dropdown = alt.binding_select(options=['Europe','Japan','USA'])
selection = alt.selection_single(fields=['Origin'], bind=input_dropdown, name='Country of ')
color = alt.condition(selection,
alt.Color('Origin:N', legend=None),
alt.value('lightgray'))

alt.Chart(cars).mark_point().encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color='Origin:N',
tooltip='Name:N'
).add_selection(
selection
).transform_filter(
selection
)


Scale Binding
^^^^^^^^^^^^^
With interval selections, the bind property can be set to the value of :"scales":. In these cases, the binding will automatically respond to the panning and zooming along the chart:

.. altair-plot::

selection = alt.selection_interval(bind="scales")
color = alt.condition(selection,
alt.Color('Origin:N', legend=None),
alt.value('lightgray'))

alt.Chart(cars).mark_point().encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color='Origin:N',
tooltip='Name:N'
).add_selection(
selection
)




Further Examples
~~~~~~~~~~~~~~~~
Now that you understand the basics of Altair selections, you might wish to look
Now that you understand the basics of Altair selections and bindings, you might wish to look
through the :ref:`gallery-category-Interactive Charts` section of the example gallery
for ideas about how they can be applied to more interesting charts.

Expand Down

0 comments on commit 701c656

Please sign in to comment.