matplotlib.widgets
按照 cmets 中的建议,一种方法是使用matplotlib.widgets,您可以阅读更多关于它们的信息here,但对于实际实现,我发现它们的Sliders 和@987654323 示例最有用@。使用您的最小示例,我能想到的最简单的改编(看起来不错)如下所示:
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()
通过各种过滤设置,结果如下所示:
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')
各种过滤设置的结果如下:
当然,配置布局等有很多选项。
此解决方案主要用于 Jupyter Notebook,
虽然如果你想将此功能嵌入到其他地方,你
可以阅读Embedding Jupyter Widgets in Other Contexts than the
Notebook。