python - 如何在图表中添加过滤器

标签 python matplotlib graph widget filtering

代码如下

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")
enter image description here
  • 如何在图形本身中添加过滤器,用户必须有权选择哪个 product必须显示在图形中和 count也让我们说如果 count > 11那么只有铅笔必须出现。
  • 有没有其他方法可以做到这一点?
  • 如果一列是日期列,我们是否也可以使用日期列进行过滤
  • 最佳答案

    matplotlib.widgets
    正如评论中所建议的,一种方法是使用 matplotlib.widgets你可以阅读更多关于他们的信息 here ,但对于实际实现,我发现他们的示例 Sliders 最有用和 Check buttons .使用您的最小示例,我能想到的最简单的改编(看起来不错)看起来像这样:

    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()
    
    使用各种过滤设置,结果如下所示:
    enter image description here

    ipywidgets(Jupyter 笔记本)
    我建议也尝试 ipywidgets ,它有比 matplotlib.widgets 更好的用户界面.您可以阅读更多关于 Using 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')
    
    具有各种过滤设置的结果如下所示:
    enter image description here
    当然,配置布局等有很多选项。

    This solution is designed to work primarily in Jupyter Notebook, though if you'd like to embed this functionality somewhere else, you can read about Embedding Jupyter Widgets in Other Contexts than the Notebook.

    关于python - 如何在图表中添加过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62424486/

    相关文章:

    algorithm - 拓扑排序变体算法

    python - 在 matplotlib 线图上向 x 轴和图例添加月份

    python - 谷歌应用引擎: LinkProperty to string

    python - 使用 python 渲染 Latex 文本

    python - 在哪里可以找到函数的 kwargs/args 文档

    python - 停止在 spyder 中显示绘图

    PHPlot 不显示图像

    python - 重新排列列表中元素的更好方法

    python - pathlib glob ('*' ) 和 iterdir 有什么区别?

    algorithm - 带加重边缘的 1/0 背包变体