IPywidgets手册在很大程度上非常有用,但缺乏关于如何创建复杂仪表板的一些解释。特别是,我想知道如何:
dict
的方式执行此操作,以便随后我可以实现按钮保存仪表板的配置并将其加载到JSON文件。为了使这个问题更加具体,我设计了一个当前方法的最小例子,该例子基于a design pattern我在@ Jupyter Widgets channel on Gitter上从@jasongrout收到的;在回答时,请通过重新实现此示例来证明您的设计模式,确保明确满足上述两个标准:
from IPython.display import display
import IPython.display as ipd
import ipywidgets as widgets
import matplotlib.pyplot as plt
class ModelUI:
def __init__(self):
self.par = dict()
self.initUI()
def initUI(self):
self.funcPars = widgets.VBox()
self.initLinear()
self.initQuadratic()
self.initFunc()
self.initButton()
self.initOutput()
self.controls = widgets.HBox([
self.func,
self.funcPars,
self.plot
])
self.UI = widgets.VBox([
self.controls,
self.output
])
def initFunc(self):
self.func = widgets.Dropdown(
description="Function:",
options=[
"Linear",
"Quadratic"
])
self.func.observe(self.updateFunc, "value")
self.updateFunc(None)
def initButton(self):
self.plot = widgets.Button(description="Plot")
self.plot.on_click(self.plotFunction)
def updateFunc(self, change):
if self.func.value == "Linear":
self.funcPars.children = self.linPars
self.par['func'] = "Linear"
elif self.func.value == "Quadratic":
self.funcPars.children = self.quadPars
self.par['func'] = "Quadratic"
else:
pass
def initLinear(self):
self.m = widgets.FloatSlider(
description="m",
min=-10, max=10, value=2)
self.k = widgets.FloatSlider(
description="k",
min=-10, max=10, value=1)
self.linPars = [self.m, self.k]
self.m.observe(self.updateLinear, "value")
self.k.observe(self.updateLinear, "value")
self.updateLinear(None)
def updateLinear(self, change):
self.par['m'] = self.m.value
self.par['k'] = self.k.value
def initQuadratic(self):
self.a = widgets.FloatSlider(
description="a",
min=-10, max=10, value=1)
self.b = widgets.FloatSlider(
description="b",
min=-10, max=10, value=2)
self.c = widgets.FloatSlider(
description="c",
min=-10, max=10, value=3)
self.quadPars = [self.a, self.b, self.c]
self.a.observe(self.updateQuadratic, "value")
self.b.observe(self.updateQuadratic, "value")
self.c.observe(self.updateQuadratic, "value")
self.updateQuadratic(None)
def updateQuadratic(self, change):
self.par['a'] = self.a.value
self.par['b'] = self.b.value
self.par['c'] = self.c.value
def initOutput(self):
self.output = widgets.Output()
self.plotFunction(None)
def plotFunction(self, change):
self.function = {
"Linear": lambda x: self.par['m']*x + self.par['k'],
"Quadratic": lambda x: self.par['a']*x**2 + self.par['b']*x + self.par['c']
}
with self.output:
ipd.clear_output()
xvals = [ i/10 for i in range(-100,100)]
yvals = list(map(self.function[self.par['func']], xvals))
plt.plot(xvals,yvals)
plt.show()
def _ipython_display_(self):
display(self.UI)
ModelUI()