IPython Notebook/Matplotlib: Interactive show/hide graphs on a plot, is it possible?

Rami

I am using IPython Notebook and Matplotlib to visualise some data, with inline display mode (i.e. I want to display and interact with my plots on the web interface of IPython Notebook).

I have a plot showing several different graphs and I would like to have an interactive interface (a set of checkboxes for example) that allow me to hide or show the graphs.

My plot looks like this:

Difficult to explore the 9 graphs together, better to hide some of them and show others

I another word: I have a plot where I display many different graphs, each graph is a line and it has its own legend. I would like to add a set of check-boxes to the plot, each one for a graph. When the checkpoint is checked the graph will be visible, when unchecked the graph will disappear.

tacaswell

To do this you need references to the artists created by your plotting routine. The plotting methods attached to the DataFrame objects return the Axes object they plotted to instead (this is useful for simple things, but makes complex things impossible) so, some plotting code:

%matplotlib notebook
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib

def pandas_plot(ax, df, style_cycle, **kwargs):
    """
    Plot a pandas DataFrame

    Parameters
    ----------
    ax : matplotlib.axes.Axes
        The axes to plot to

    df : pd.DataFrame
        The data to plot

    style_cycle : Cycler
        Something that when iterated over yields style dict

    Returns
    -------
    ret : dict
        Dictionary of line2d artists added 
    """
    ret = {}
    x = df.index
    for n, sty in zip(df.columns, style_cycle):
        sty.update(kwargs)
        ln, = ax.plot(x, df[n], label=n, **sty)
        ret[n] = ln
    ax.legend()
    return ret

Now some code to set up the widget interface (this is doing more than you asked for, but this is what I have pre-made from my scipy talk):

from IPython.html.widgets import *
from IPython.display import display

def widget_function_factory(arts):
    """
    Generate fulnction + args to pass to interactive
    Parameters
    ----------
    arts : dict
        dictionary of Line2D

    """

    name = Dropdown(options=list(arts.keys()))

    def set_all(_, old_line, new_line):
        ln = arts[new_line]
        lw.value = ln.get_lw()
        alph.value = ln.get_alpha() or 1
        visible.value = ln.get_visible()
        markevery.value = ln.get_markevery()
        marker.value = ln.get_marker()

    def set_lw(_, old_lw, new_lw):
        ln = arts[name.value]
        arts[name.value].set_lw(new_lw)
        arts[name.value].axes.legend()

    def set_alpha(_, old_value, new_value):
        ln = arts[name.value]
        ln.set_alpha(new_value)
        ln.axes.legend()

    def set_visible(_, old_value, new_value):
        ln = arts[name.value]
        ln.set_visible(new_value)
        ln.axes.legend()

    def set_markevery(_, old_value, new_value):
        ln = arts[name.value]
        ln.set_markevery(new_value)

    def set_marker(_, old_value, new_value):
        ln = arts[name.value]
        ln.set_marker(new_value)
        ln.axes.legend()

    lw = FloatSlider(min=1, max=5, description='lw: ')
    alph = FloatSlider(min=0, max=1, description='alpha: ')
    visible = Checkbox(description='visible: ')
    markevery = IntSlider(min=1, max=15, description='markevery: ')
    marker = Dropdown(options={v:k for k, v in matplotlib.markers.MarkerStyle.markers.items()},
                     description='marker: ')

    name.on_trait_change(set_all, 'value')
    lw.on_trait_change(set_lw, 'value')
    alph.on_trait_change(set_alpha, 'value')
    visible.on_trait_change(set_visible, 'value')
    markevery.on_trait_change(set_markevery, 'value')
    marker.on_trait_change(set_marker, 'value')
    display(name, lw, alph, marker, markevery, visible)
    set_all(None, None, name.value)

do the plotting:

th = np.linspace(0, 2*np.pi, 128)
df = pd.DataFrame({'sin': np.sin(th),
                   'shift +': np.sin(th + np.pi / 3), 
                   'shift -': np.sin(th - np.pi / 3)}, index=th)

fig, ax = plt.subplots()
from cycler import cycler
style_cycle = cycler('color',['r', 'black', 'pink']) + cycler('marker', 'sxo')
#style_cycle = [{'color': 'r', 'marker': 's'},
#               {'color': 'black', 'marker': 'x'},
#               {'color': 'pink', 'marker': 'o'}]
arts = pandas_plot(ax, df, style_cycle, markevery=10)
vlns = []
for x in np.arange(1, 7) * np.pi/3:
    vlns.append(plt.axvline(x, color='k', linestyle=':'))
plt.axhline(0, color='k', linestyle=':')

and create the controls

widget_function_factory(arts)

cycler is a side project that spun off of mpl (and will be a required dep for 1.5). It is currently pip installable.

See https://gist.github.com/tacaswell/7a0e5e76fb3cafa3b7cd#file-so_interactive_demo-ipynb for a demo notebook.

There is on-going work to make this easier (so that mpl Artists can auto-construct their UI elements). The infrastructure that will make that work is one of the major goals of mpl 2.1.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

iPython/Jupyter Notebook and Pandas, how to plot multiple graphs in a for loop?

From Dev

Interactive hovering Shiny graphs

From Dev

How to represent graphs with IPython

From Dev

Interactive Ipython Notebooks on Heroku

From Dev

Is it possible to program from shell (vim + tmux) and host an ipython server for the matplitlib graphs?

From Dev

Is it possible to speed up interactive IPython Notebook plots by not generating new figures every time?

From Dev

Scala library for plotting interactive graphs

From Dev

Plot two graphs in the same plot

From Dev

Cannot show the graphs on ipython notebook

From Dev

Plot with multiple graphs

From Dev

Plot with multiple graphs

From Dev

Interactive matplotlib/ipython figures on Windows

From Dev

python, ipython run interactive script

From Dev

Interactive matplotlib/ipython figures on Windows

From Dev

Using string as variable in iPython interactive

From Dev

Interactive tooltips in matplotlib plot

From Dev

jupyterlab interactive plot

From Dev

Plot inside Ipython Notebook

From Dev

Plot inside Ipython Notebook

From Dev

Multiple graphs within plot with loop

From Dev

stars plot formatting: keys on the graphs

From Dev

Multiple graphs on the same plot in seaborn

From Dev

Using ggplot to plot multiple graphs

From Dev

two graphs in one plot matlab

From Dev

All graphs are written to the same plot

From Java

Plot two graphs in same plot in R

From Dev

MATLAB: Interactive tool to "draw" a Plot?

From Dev

Jupyter Notebook: interactive plot with widgets

From Dev

Interactive scatter plot with colorbar legend