Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding documentation #1113

Merged
merged 12 commits into from
Aug 29, 2018
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:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the user-guide-selections cross reference is used a couple times elsewhere in the docs. Since you're renaming it here, it should be renamed elsewhere as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I missed this in previous. Updated found one reference as stated above.


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::
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great catch. I only found one other reference (on the weather chart which was funny given that I missed it before) I think we should be there.


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::
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line


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