如何在图表中添加过滤器

ays*_*ysh 4 python filtering graph widget matplotlib

代码如下

from io import StringIO
text = '''Product,Count
Pen,10
Pencil,15
Book, 10'''
df = pd.read_csv(StringIO(text))
df.plot(x="Product", y="Count", kind="bar")
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 如何在图表本身中添加过滤器,用户必须有权选择哪些product必须显示在图表中,count并且假设count > 11只有 Pencil 必须出现。

  • 有没有其他方法可以做到这一点?

  • 如果一列是日期列,我们是否也可以使用日期列进行过滤

Bru*_*x13 9

matplotlib.widgets

正如评论中所建议的那样,一种方法是使用matplotlib.widgets,您可以在此处阅读有关它们的更多信息,但对于实际实现,我发现它们的滑块检查按钮示例最有用。使用您的最小示例,我能想到的最简单的改编(看起来不错)看起来像这样:

import pandas as pd
from io import StringIO
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from matplotlib.widgets import Slider, CheckButtons

text = '''Product,Count
Pen,10
Pencil,15
Book,10'''
df = pd.read_csv(StringIO(text))

fig, ax = plt.subplots()
gs = gridspec.GridSpec(
    nrows = 2,
    ncols = 2,
    figure = fig,
    wspace = 0.3,
    hspace = 0.6,
    height_ratios = [2,1]
    )
ax.set_position(gs[0,:].get_position(fig))

axMinCount = fig.add_subplot(gs[1,0])
axProducts = fig.add_subplot(gs[1,1])

labels = ('Pen', 'Pencil', 'Book')
minimum = 5
actives = [True, True, True]

df.loc[actives & (df['Count'] >= minimum)].plot(
    x = 'Product', y = 'Count', kind = 'bar', ax = ax, legend = False
    )

sMinCount = Slider(axMinCount, 'Min Count', 0, 20, valinit = minimum, valstep = 1)
cProducts = CheckButtons(axProducts, labels, actives)


def update(val):
    minimum = sMinCount.val
    df_filtered = df.loc[actives & (df['Count'] >= minimum)]
    if not df_filtered.empty:
        df_filtered.plot(
        x = 'Product', y = 'Count', kind = 'bar', ax = ax, legend = False
        )
    else:
        ax.cla()

def check(label):
    index = labels.index(label)
    actives[index] = not actives[index]
    df_filtered = df.loc[actives & (df['Count'] >= minimum)]
    if not df_filtered.empty:
        df_filtered.plot(
        x = 'Product', y = 'Count', kind = 'bar', ax = ax, legend = False
        )
    else:
        ax.cla()
    
sMinCount.on_changed(update)
cProducts.on_clicked(check)

plt.show()
Run Code Online (Sandbox Code Playgroud)

使用各种过滤设置,结果如下所示:

在此处输入图片说明


ipywidgets(Jupyter 笔记本)

我建议也尝试ipywidgets,它的用户界面比matplotlib.widgets. 您可以阅读有关使用 Interact 的更多信息。使用您的最小示例:

import pandas as pd
from io import StringIO
from ipywidgets import interact

text = '''Product,Count
Pen,10
Pencil,15
Book,10'''
df = pd.read_csv(StringIO(text))

# This is a wrapper of the function that follows, providing the interactive input
@interact(MinCount = (0, 20, 1), pen = True, pencil = True, book = True)
# Note that in the core function below, you can set the starting values
def plotter_fun(MinCount = 0, pen = True, pencil = True, book = True):   
    # Filter the data using the interactive input
    df_filtered = df.loc[(pen, pencil, book) & (df['Count'] >= MinCount)]
    # If all data has been filtered out, announce it
    if df_filtered.empty:
        print('No data to show.')
    # Otherwise plot
    else:
        df_filtered.plot(x = 'Product', y = 'Count', kind = 'bar')
Run Code Online (Sandbox Code Playgroud)

具有各种过滤设置的结果如下所示:

在此处输入图片说明

当然,配置布局等有很多选项。

此解决方案旨在主要在Jupyter Notebook 中工作,但如果您想将此功能嵌入其他地方,您可以阅读有关在 Notebook 之外的其他上下文中嵌入 Jupyter 小部件的信息

  • @aysh我没有看到任何为“matplotlib.widgets”预先制作的内容,因此如果您要使用该模块,则必须为日期进行自定义。相比之下,“ipywidgets”有一个[日期选择器](https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20List.html#Date-picker)小部件,就是为此而制作的! (2认同)