
:orphan:
:html_theme.sidebar_secondary.remove:

.. This document is auto-generated by the altair-gallery extension. Do not modify directly.

.. _gallery_scatter_with_layered_histogram:


Interactive Scatter Plot and Linked Layered Histogram
=====================================================

This example shows how to link a scatter plot and a histogram
together such that clicking on a point in the scatter plot will
isolate the distribution corresponding to that point, and vice versa.


.. altair-plot::
    :remove-code:
    



    import altair as alt
    import pandas as pd
    import numpy as np

    # generate fake data
    source = pd.DataFrame({
        'gender': ['M']*1000 + ['F']*1000,
        'height':np.concatenate((
            np.random.normal(69, 7, 1000), np.random.normal(64, 6, 1000)
        )),
        'weight': np.concatenate((
            np.random.normal(195.8, 144, 1000), np.random.normal(167, 100, 1000)
        )),
        'age': np.concatenate((
            np.random.normal(45, 8, 1000), np.random.normal(51, 6, 1000)
            ))
        })

    selector = alt.selection_point(fields=['gender'])

    color_scale = alt.Scale(domain=['M', 'F'],
                            range=['#1FC3AA', '#8624F5'])
    color = (
        alt.when(selector)
        .then(alt.Color("gender:N", scale=color_scale))
        .otherwise(alt.value("lightgray"))
    )
    base = alt.Chart(source).properties(
        width=250,
        height=250
    ).add_params(selector)

    points = base.mark_point(filled=True, size=200).encode(
        x=alt.X('mean(height):Q', scale=alt.Scale(domain=[0,84])),
        y=alt.Y('mean(weight):Q', scale=alt.Scale(domain=[0,250])),
        color=color,
    )

    hists = base.mark_bar(opacity=0.5, thickness=100).encode(
        x=alt.X('age',
                bin=alt.Bin(step=5), # step keeps bin size the same
                scale=alt.Scale(domain=[0,100])),
        y=alt.Y('count()',
                stack=None,
                scale=alt.Scale(domain=[0,350])),
        color=alt.Color('gender:N',
                        scale=color_scale)
    ).transform_filter(
        selector
    )


    points | hists


.. tab-set::

    .. tab-item:: Method syntax
        :sync: method

        .. code:: python



            import altair as alt
            import pandas as pd
            import numpy as np

            # generate fake data
            source = pd.DataFrame({
                'gender': ['M']*1000 + ['F']*1000,
                'height':np.concatenate((
                    np.random.normal(69, 7, 1000), np.random.normal(64, 6, 1000)
                )),
                'weight': np.concatenate((
                    np.random.normal(195.8, 144, 1000), np.random.normal(167, 100, 1000)
                )),
                'age': np.concatenate((
                    np.random.normal(45, 8, 1000), np.random.normal(51, 6, 1000)
                    ))
                })

            selector = alt.selection_point(fields=['gender'])

            color_scale = alt.Scale(domain=['M', 'F'],
                                    range=['#1FC3AA', '#8624F5'])
            color = (
                alt.when(selector)
                .then(alt.Color("gender:N").scale(color_scale))
                .otherwise(alt.value("lightgray"))
            )
            base = alt.Chart(source).properties(
                width=250,
                height=250
            ).add_params(selector)

            points = base.mark_point(filled=True, size=200).encode(
                alt.X('mean(height):Q').scale(domain=[0,84]),
                alt.Y('mean(weight):Q').scale(domain=[0,250]),
                color=color,
            )

            hists = base.mark_bar(opacity=0.5, thickness=100).encode(
                alt.X('age')
                    .bin(step=5) # step keeps bin size the same
                    .scale(domain=[0,100]),
                alt.Y('count()')
                    .stack(None)
                    .scale(domain=[0,350]),
                alt.Color('gender:N').scale(color_scale)
            ).transform_filter(
                selector
            )

            points | hists


    .. tab-item:: Attribute syntax
        :sync: attribute

        .. code:: python



            import altair as alt
            import pandas as pd
            import numpy as np

            # generate fake data
            source = pd.DataFrame({
                'gender': ['M']*1000 + ['F']*1000,
                'height':np.concatenate((
                    np.random.normal(69, 7, 1000), np.random.normal(64, 6, 1000)
                )),
                'weight': np.concatenate((
                    np.random.normal(195.8, 144, 1000), np.random.normal(167, 100, 1000)
                )),
                'age': np.concatenate((
                    np.random.normal(45, 8, 1000), np.random.normal(51, 6, 1000)
                    ))
                })

            selector = alt.selection_point(fields=['gender'])

            color_scale = alt.Scale(domain=['M', 'F'],
                                    range=['#1FC3AA', '#8624F5'])
            color = (
                alt.when(selector)
                .then(alt.Color("gender:N", scale=color_scale))
                .otherwise(alt.value("lightgray"))
            )
            base = alt.Chart(source).properties(
                width=250,
                height=250
            ).add_params(selector)

            points = base.mark_point(filled=True, size=200).encode(
                x=alt.X('mean(height):Q', scale=alt.Scale(domain=[0,84])),
                y=alt.Y('mean(weight):Q', scale=alt.Scale(domain=[0,250])),
                color=color,
            )

            hists = base.mark_bar(opacity=0.5, thickness=100).encode(
                x=alt.X('age',
                        bin=alt.Bin(step=5), # step keeps bin size the same
                        scale=alt.Scale(domain=[0,100])),
                y=alt.Y('count()',
                        stack=None,
                        scale=alt.Scale(domain=[0,350])),
                color=alt.Color('gender:N',
                                scale=color_scale)
            ).transform_filter(
                selector
            )


            points | hists
