Как добавить фильтр на график - PullRequest
4 голосов
/ 17 июня 2020

Код ниже

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")

введите описание изображения здесь

  • Как добавить фильтр в сам график, чтобы пользователь мог выбрать, какой product должен отображаться на графике, а count также скажем, если count > 11 тогда должен появиться только карандаш.

  • Есть ли альтернативный способ сделать это?

  • ЕСЛИ один столбец - столбец даты, может мы также выполняем фильтрацию с столбцом даты

1 Ответ

9 голосов
/ 20 июня 2020

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()

С различными настройками фильтрации результат выглядит так:

enter image description here


ipywidgets (Jupyter notebook)

I'd suggest also trying ipywidgets, which have a much nicer user interface than matplotlib.widgets. You can read more about Использование 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

Of course, there are many options for configuring the layout etc.

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 Встраивание виджетов Jupyter в другие контексты, кроме Notebook .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...