【问题标题】:IPython Notebook/Matplotlib: Interactive show/hide graphs on a plot, is it possible?IPython Notebook/Matplotlib:在绘图上交互式显示/隐藏图表,这可能吗?
【发布时间】:2015-10-13 21:33:42
【问题描述】:

我正在使用 IPython Notebook 和 Matplotlib 以内联显示模式可视化一些数据(即我想在 IPython Notebook 的 Web 界面上显示我的绘图并与之交互)。

我有一个显示几个不同图表的图,我想要一个交互式界面(例如一组复选框),允许我隐藏或显示图表。

我的情节是这样的:

我换个说法:我有一个图,其中显示了许多不同的图表,每个图表都是一条线,并且有自己的图例。我想在图中添加一组复选框,每个复选框都用于图表。选中检查点时,图表将可见,取消选中时,图表将消失。

【问题讨论】:

  • 是的,这是可能的。你可能想看看ipywidgets。但是,您的问题可能过于宽泛而无法回答。
  • 谢谢 cel :) 我的问题是:我有一个情节,其中我绘制了 9 个不同的图形(线),每个图形都有自己的图例。我想在绘图旁边添加一组复选框(9 个复选框),每个复选框对应一个图表。选中检查点时,图表将可见,取消选中时,图表将消失。
  • %matplotlib notebook 将为您提供一个可以平移/缩放的交互式图形。
  • @tcaswell 不会隐藏/显示他所询问的个别行。
  • @tcaswell 正如 Leb 所说,这将不允许我显示和隐藏线条。

标签: python matplotlib ipython-notebook


【解决方案1】:

为此,您需要参考由您的绘图程序创建的艺术家。附加到 DataFrame 对象的绘图方法返回它们所绘制的 Axes 对象(这对简单的事情很有用,但使复杂的事情变得不可能)所以,一些绘图代码:

%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

现在一些代码来设置小部件界面(这比你要求的要多,但这是我从我的 scipy 演讲中预先制作的):

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)

进行绘图:

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=':')

并创建控件

widget_function_factory(arts)

cycler 是一个从 mpl 衍生出来的副项目(将是 1.5 所需的 dep)。它目前是 pip 可安装的。

有关演示笔记本,请参阅 https://gist.github.com/tacaswell/7a0e5e76fb3cafa3b7cd#file-so_interactive_demo-ipynb

正在进行的工作使这更容易(以便 mpl 艺术家可以自动构建他们的 UI 元素)。实现这项工作的基础设施是 mpl 2.1 的主要目标之一。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 2015-11-01
    • 2019-10-12
    • 2016-11-16
    • 2017-05-11
    • 2014-06-28
    相关资源
    最近更新 更多