def __init__(self, data, model=None, all_models=None, axes_style={}, data_style={}, init_style={}, best_style={}, **kwargs): # Dropdown menu of all subclasses of Model, incl. user-defined. self.models_menu = Dropdown() # Dropbox API is very different between IPy 2.x and 3.x. if IPY2: if all_models is None: all_models = {m.__name__: m for m in Model.__subclasses__()} self.models_menu.values = all_models else: if all_models is None: all_models = [(m.__name__, m) for m in Model.__subclasses__()] self.models_menu.options = all_models self.models_menu.on_trait_change(self._on_model_value_change, 'value') # Button to trigger fitting. self.fit_button = Button(description='Fit') self.fit_button.on_click(self._on_fit_button_click) # Button to trigger guessing. self.guess_button = Button(description='Auto-Guess') self.guess_button.on_click(self._on_guess_button_click) # Parameter widgets are not built here. They are (re-)built when # the model is (re-)set. super(NotebookFitter, self).__init__(data, model, axes_style, data_style, init_style, best_style, **kwargs)
def _widget_abbrev(o): """Make widgets from abbreviations: single values, lists or tuples.""" float_or_int = (float, int) if isinstance(o, (list, tuple)): if o and all(isinstance(x, string_types) for x in o): return DropdownWidget(values=[unicode_type(k) for k in o]) elif _matches(o, (float_or_int, float_or_int)): min, max, value = _get_min_max_value(o[0], o[1]) if all(isinstance(_, int) for _ in o): cls = IntSliderWidget else: cls = FloatSliderWidget return cls(value=value, min=min, max=max) elif _matches(o, (float_or_int, float_or_int, float_or_int)): step = o[2] if step <= 0: raise ValueError("step must be >= 0, not %r" % step) min, max, value = _get_min_max_value(o[0], o[1], step=step) if all(isinstance(_, int) for _ in o): cls = IntSliderWidget else: cls = FloatSliderWidget return cls(value=value, min=min, max=max, step=step) else: return _widget_abbrev_single_value(o)
def __init__(self, data, model=None, all_models=None, axes_style={}, data_style={}, init_style={}, best_style={}, **kwargs): # Dropdown menu of all subclasses of Model, incl. user-defined. self.models_menu = Dropdown() # Dropbox API is very different between IPy 2.x and 3.x. if IPY2: if all_models is None: all_models = dict([(m.__name__, m) for m in Model.__subclasses__()]) self.models_menu.values = all_models else: if all_models is None: all_models = [(m.__name__, m) for m in Model.__subclasses__()] self.models_menu.options = all_models self.models_menu.on_trait_change(self._on_model_value_change, 'value') # Button to trigger fitting. self.fit_button = Button(description='Fit') self.fit_button.on_click(self._on_fit_button_click) # Button to trigger guessing. self.guess_button = Button(description='Auto-Guess') self.guess_button.on_click(self._on_guess_button_click) # Parameter widgets are not built here. They are (re-)built when # the model is (re-)set. super(NotebookFitter, self).__init__(data, model, axes_style, data_style, init_style, best_style, **kwargs)
def _widget_abbrev_single_value(o): """Make widgets from single values, which can be used as parameter defaults.""" if isinstance(o, string_types): return TextWidget(value=unicode_type(o)) elif isinstance(o, dict): return DropdownWidget(values=o) elif isinstance(o, bool): return CheckboxWidget(value=o) elif isinstance(o, float): min, max, value = _get_min_max_value(None, None, o) return FloatSliderWidget(value=o, min=min, max=max) elif isinstance(o, int): min, max, value = _get_min_max_value(None, None, o) return IntSliderWidget(value=o, min=min, max=max) else: return None
def __init__(self, data, model=None, **kwargs): # Dropdown menu of all subclasses of Model, incl. user-defined. self.models_menu = Dropdown() all_models = {m.__name__: m for m in Model.__subclasses__()} self.models_menu.values = all_models self.models_menu.on_trait_change(self._on_model_value_change, 'value') # Button to trigger fitting. self.fit_button = Button(description='Fit') self.fit_button.on_click(self._on_fit_button_click) # Button to trigger guessing. self.guess_button = Button(description='Auto-Guess') self.guess_button.on_click(self._on_guess_button_click) # Parameter widgets are not built here. They are (re-)built when # the model is (re-)set. super(NotebookFitter, self).__init__(data, model, **kwargs)
class NotebookFitter(BaseFitter): __doc__ = _COMMON_DOC + """ If IPython is available, it uses the IPython notebook's rich display to fit data interactively in a web-based GUI. The Parameters are represented in a web-based form that is kept in sync with `current_params`. All subclasses to Model, including user-defined ones, are shown in a drop-down menu. Clicking the "Fit" button updates a plot, as above, and updates the Parameters in the form to reflect the best fit. """ + _COMMON_EXAMPLES_DOC def __init__(self, data, model=None, **kwargs): # Dropdown menu of all subclasses of Model, incl. user-defined. self.models_menu = Dropdown() all_models = {m.__name__: m for m in Model.__subclasses__()} self.models_menu.values = all_models self.models_menu.on_trait_change(self._on_model_value_change, 'value') # Button to trigger fitting. self.fit_button = Button(description='Fit') self.fit_button.on_click(self._on_fit_button_click) # Button to trigger guessing. self.guess_button = Button(description='Auto-Guess') self.guess_button.on_click(self._on_guess_button_click) # Parameter widgets are not built here. They are (re-)built when # the model is (re-)set. super(NotebookFitter, self).__init__(data, model, **kwargs) def _repr_html_(self): display(self.models_menu) button_box = Box() button_box.children = [self.fit_button, self.guess_button] display(button_box) button_box.add_class('hbox') for pw in self.param_widgets: display(pw) self.plot() def guess(self): guessing_successful = super(NotebookFitter, self).guess() self.guess_button.disabled = not guessing_successful def _finalize_model(self, value): first_run = not hasattr(self, 'param_widgets') if not first_run: # Remove all Parameter widgets, and replace them with widgets # for the new model. for pw in self.param_widgets: pw.close() self.models_menu.value = value self.param_widgets = [ParameterWidgetGroup(p) for _, p in self._current_params.items()] if not first_run: for pw in self.param_widgets: display(pw) def _finalize_params(self): for pw in self.param_widgets: pw.value = self._current_params[pw.name].value pw.min = self._current_params[pw.name].min pw.max = self._current_params[pw.name].max pw.vary = self._current_params[pw.name].vary def plot(self): clear_output(wait=True) super(NotebookFitter, self).plot() def fit(self): super(NotebookFitter, self).fit() self.plot()
def __init__(self, domains, components, circuit=None, **kwargs): super(CircuitBuilder, self).__init__(**kwargs) self.button_text = "Launch CircuitBuilder" self.description = circuit.name def _resize_inputs(el): el.set_css({"width": "100px"}) ##### make controls self.basic_controls = HorizontalContainer() self.add_component_controls = HorizontalContainer() self.add_port_controls = HorizontalContainer() self.change_component_controls = HorizontalContainer() self.change_port_controls = HorizontalContainer() # 1) basic controls self.reset_view_btn = ButtonWidget(description="Reset view") self.reset_view_btn.on_click(self.reset_view) self.circname = TextWidget(description="Circuit name", value=circuit.name) self.circname.on_displayed(_resize_inputs) self.rename_circ_btn = ButtonWidget(description="Rename") self.rename_circ_btn.on_click(self.rename_circuit) self.add_port_btn = ButtonWidget(description="New Port") self.add_port_btn.on_click(self.show_add_port_controls) self.add_comp_btn = ButtonWidget(description="New Component") self.add_comp_btn.on_click((self.show_add_comp_controls)) # self.download_btn = ButtonWidget(description="SaveAsSVG") # self.download_btn.on_click() self.basic_controls.children = [ self.reset_view_btn, self.circname, self.rename_circ_btn, self.add_port_btn, self.add_comp_btn, ] # 2) add component self.add_comp_type = DropdownWidget(description="ComponentType") self.add_comp_name = TextWidget(description="Component name") self.add_comp_name.on_displayed(_resize_inputs) self.add_comp_add = ButtonWidget(description="Add Component") self.add_comp_add.on_click(self.add_component) self.add_comp_back = ButtonWidget(description="Back") self.add_comp_back.on_click(self.back) self.add_component_controls.children = [ self.add_comp_type, self.add_comp_name, self.add_comp_add, self.add_comp_back, ] # 3) add port self.add_port_name = TextWidget(description="Port name") self.add_port_name.on_displayed(_resize_inputs) self.add_port_domain = DropdownWidget(description="Domain") self.add_port_domain.on_trait_change(self._update_port_directions, "value_name") self.add_port_direction = DropdownWidget(description="Direction", values={"in": "Input", "out": "Output"}) self.add_port_add = ButtonWidget(description="Add Port") self.add_port_add.on_click(self.add_port) self.add_port_back = ButtonWidget(description="Back") self.add_port_back.on_click(self.back) self.add_port_controls.children = [ self.add_port_name, self.add_port_domain, self.add_port_direction, self.add_port_add, self.add_port_back, ] # 4) change component self.mod_comp_name = TextWidget(description="Component name") self.mod_comp_name.on_displayed(_resize_inputs) self.mod_comp_rename = ButtonWidget(description="Rename") self.mod_comp_rename.on_click(self.rename_component) self.mod_comp_delete = ButtonWidget(description="Delete") self.mod_comp_delete.on_click(self.delete_component) self.mod_comp_back = ButtonWidget(description="Back") self.mod_comp_back.on_click(self.back) self.change_component_controls.children = [ self.mod_comp_name, self.mod_comp_rename, self.mod_comp_delete, self.mod_comp_back, ] # 5) change port self.mod_port_name = TextWidget(description="Port name") self.mod_port_name.on_displayed(_resize_inputs) self.mod_port_rename = ButtonWidget(description="Rename") self.mod_port_rename.on_click(self.rename_port) self.mod_port_dec = ButtonWidget(description="<") self.mod_port_inc = ButtonWidget(description=">") self.mod_port_dec.on_click(self.dec_port_order) self.mod_port_inc.on_click(self.inc_port_order) self.mod_port_delete = ButtonWidget(description="Delete") self.mod_port_delete.on_click(self.delete_port) self.mod_port_back = ButtonWidget(description="Back") self.mod_port_back.on_click(self.back) self.change_port_controls.children = [ self.mod_port_name, self.mod_port_rename, self.mod_port_dec, self.mod_port_inc, self.mod_port_delete, self.mod_port_back, ] # has to come at end!! self.domains = domains self.components = components self.circuit = circuit self.circuit.on_trait_change(self._handle_circuit_selection, "selected_element") self.circuit.on_trait_change(self._handle_circuit_name, "name") self.children = [ self.basic_controls, self.add_component_controls, self.add_port_controls, self.change_component_controls, self.change_port_controls, self.circuit ] self.back()
class CircuitBuilder(PopupWidget): """ Adds additional controls to the circuit widget for adding/removing external ports and component instances. """ _view_name = Unicode("CircuitBuilderView", sync=True) circuit = Instance(klass=Circuit, sync=True) domains = List() _domains_by_name = Dict() components = List() _components_by_name = Dict() def _components_changed(self, name, old, new): self.add_comp_type.values = {c.name: c.name for c in new} self._components_by_name = {c.name: c for c in new} def _domains_changed(self, name, old, new): self.add_port_domain.values = {d.name: d.name for d in new} self.add_port_domain.value_name = new[0].name self._domains_by_name = {d.name: d for d in new} self._update_port_directions() def __init__(self, domains, components, circuit=None, **kwargs): super(CircuitBuilder, self).__init__(**kwargs) self.button_text = "Launch CircuitBuilder" self.description = circuit.name def _resize_inputs(el): el.set_css({"width": "100px"}) ##### make controls self.basic_controls = HorizontalContainer() self.add_component_controls = HorizontalContainer() self.add_port_controls = HorizontalContainer() self.change_component_controls = HorizontalContainer() self.change_port_controls = HorizontalContainer() # 1) basic controls self.reset_view_btn = ButtonWidget(description="Reset view") self.reset_view_btn.on_click(self.reset_view) self.circname = TextWidget(description="Circuit name", value=circuit.name) self.circname.on_displayed(_resize_inputs) self.rename_circ_btn = ButtonWidget(description="Rename") self.rename_circ_btn.on_click(self.rename_circuit) self.add_port_btn = ButtonWidget(description="New Port") self.add_port_btn.on_click(self.show_add_port_controls) self.add_comp_btn = ButtonWidget(description="New Component") self.add_comp_btn.on_click((self.show_add_comp_controls)) # self.download_btn = ButtonWidget(description="SaveAsSVG") # self.download_btn.on_click() self.basic_controls.children = [ self.reset_view_btn, self.circname, self.rename_circ_btn, self.add_port_btn, self.add_comp_btn, ] # 2) add component self.add_comp_type = DropdownWidget(description="ComponentType") self.add_comp_name = TextWidget(description="Component name") self.add_comp_name.on_displayed(_resize_inputs) self.add_comp_add = ButtonWidget(description="Add Component") self.add_comp_add.on_click(self.add_component) self.add_comp_back = ButtonWidget(description="Back") self.add_comp_back.on_click(self.back) self.add_component_controls.children = [ self.add_comp_type, self.add_comp_name, self.add_comp_add, self.add_comp_back, ] # 3) add port self.add_port_name = TextWidget(description="Port name") self.add_port_name.on_displayed(_resize_inputs) self.add_port_domain = DropdownWidget(description="Domain") self.add_port_domain.on_trait_change(self._update_port_directions, "value_name") self.add_port_direction = DropdownWidget(description="Direction", values={"in": "Input", "out": "Output"}) self.add_port_add = ButtonWidget(description="Add Port") self.add_port_add.on_click(self.add_port) self.add_port_back = ButtonWidget(description="Back") self.add_port_back.on_click(self.back) self.add_port_controls.children = [ self.add_port_name, self.add_port_domain, self.add_port_direction, self.add_port_add, self.add_port_back, ] # 4) change component self.mod_comp_name = TextWidget(description="Component name") self.mod_comp_name.on_displayed(_resize_inputs) self.mod_comp_rename = ButtonWidget(description="Rename") self.mod_comp_rename.on_click(self.rename_component) self.mod_comp_delete = ButtonWidget(description="Delete") self.mod_comp_delete.on_click(self.delete_component) self.mod_comp_back = ButtonWidget(description="Back") self.mod_comp_back.on_click(self.back) self.change_component_controls.children = [ self.mod_comp_name, self.mod_comp_rename, self.mod_comp_delete, self.mod_comp_back, ] # 5) change port self.mod_port_name = TextWidget(description="Port name") self.mod_port_name.on_displayed(_resize_inputs) self.mod_port_rename = ButtonWidget(description="Rename") self.mod_port_rename.on_click(self.rename_port) self.mod_port_dec = ButtonWidget(description="<") self.mod_port_inc = ButtonWidget(description=">") self.mod_port_dec.on_click(self.dec_port_order) self.mod_port_inc.on_click(self.inc_port_order) self.mod_port_delete = ButtonWidget(description="Delete") self.mod_port_delete.on_click(self.delete_port) self.mod_port_back = ButtonWidget(description="Back") self.mod_port_back.on_click(self.back) self.change_port_controls.children = [ self.mod_port_name, self.mod_port_rename, self.mod_port_dec, self.mod_port_inc, self.mod_port_delete, self.mod_port_back, ] # has to come at end!! self.domains = domains self.components = components self.circuit = circuit self.circuit.on_trait_change(self._handle_circuit_selection, "selected_element") self.circuit.on_trait_change(self._handle_circuit_name, "name") self.children = [ self.basic_controls, self.add_component_controls, self.add_port_controls, self.change_component_controls, self.change_port_controls, self.circuit ] self.back() def _handle_circuit_selection(self): e = self.circuit.selected_element if e: if isinstance(e, Port) and e.is_ext: self.back() self.show_mod_port_controls(e) return elif isinstance(e, ComponentInstance): self.back() self.show_mod_comp_controls(e) return self.back() def _handle_circuit_name(self): self.circname.value = self.circuit.name self.description = self.circuit.name def reset_view(self, *_): self.circuit.zoom = (0., 0., 1.) def back(self, *_): for c in [ self.add_component_controls, self.add_port_controls, self.change_component_controls, self.change_port_controls, ]: c.visible = False self.basic_controls.visible = True def show_mod_comp_controls(self, c): self.basic_controls.visible = False self.change_component_controls.visible = True self.mod_comp_name.value = c.name def show_mod_port_controls(self, p): self.basic_controls.visible = False self.change_port_controls.visible = True self.mod_port_name.value = p.name def show_add_port_controls(self, *_): self.basic_controls.visible = False self.add_port_controls.visible = True def show_add_comp_controls(self, *_): self.basic_controls.visible = False self.add_component_controls.visible = True def _update_port_directions(self): d = self._domains_by_name.get(self.add_port_domain.value_name, False) if isinstance(d, Domain): self.add_port_direction.visible = d.causal def rename_circuit(self, *_): if len(self.circname.value): self.circuit.name = self.circname.value def add_component(self, *_): ctype = self._components_by_name[self.add_comp_type.value_name] cname = self.add_comp_name.value if len(cname) and not cname in self.circuit.c: new_comp = ctype.make_instance(cname) self.circuit.component_instances = self.circuit.component_instances + [new_comp] def add_port(self, *_): d = self._domains_by_name[self.add_port_domain.value_name] dir = self.add_port_direction.value_name if not d.causal: dir = "inout" pname = self.add_port_name.value if len(pname) and not pname in self.circuit.p: newp = Port(name=pname, domain=d, direction=dir) self.circuit.ports = self.circuit.ports + [newp] def rename_component(self, *_): c = self.circuit.selected_element if not isinstance(c, ComponentInstance): return newname = self.mod_comp_name.value if len(newname) and not newname in self.circuit.c: del self.circuit.c[c.name] c.name = newname self.circuit.c[c.name] = c def rename_port(self, *_): p = self.circuit.selected_element if not isinstance(p, Port): return newname = self.mod_port_name.value if len(newname) and not newname in self.circuit.p: del self.circuit.p[p.name] p.name = newname self.circuit.p[p.name] = p def delete_component(self, *_): c = self.circuit.selected_element if not isinstance(c, ComponentInstance) \ or not c in self.circuit.component_instances: return self.circuit.component_instances = filter(lambda cc: cc is not c, self.circuit.component_instances) for p in c.ports: for cc in p.connections_in + p.connections_out: cc.remove() self.circuit.selected_element = None def delete_port(self, *_): p = self.circuit.selected_element if not isinstance(p, Port) \ or not p in self.circuit.ports: return self.circuit.ports = filter(lambda pp: pp is not p, self.circuit.ports) for c in p.connections_in + p.connections_out: c.remove() self.circuit.selected_element = None def dec_port_order(self, *_): p = self.circuit.selected_element if not isinstance(p, Port) \ or not p in self.circuit.ports: return ps = list(self.circuit.ports) ii = ps.index(p) ps.pop(ii) ii = max(1, ii) self.circuit.ports = ps[:ii-1] + [p] + ps[ii-1:] def inc_port_order(self, *_): p = self.circuit.selected_element if not isinstance(p, Port) \ or not p in self.circuit.ports: return ps = list(self.circuit.ports) ii = ps.index(p) ps.pop(ii) self.circuit.ports = ps[:ii+1] + [p] + ps[ii+1:]
class NotebookFitter(MPLFitter): __doc__ = _COMMON_DOC + """ If IPython is available, it uses the IPython notebook's rich display to fit data interactively in a web-based GUI. The Parameters are represented in a web-based form that is kept in sync with `current_params`. All subclasses to Model, including user-defined ones, are shown in a drop-down menu. Clicking the "Fit" button updates a plot, as above, and updates the Parameters in the form to reflect the best fit. Parameters ---------- data : array-like model : lmfit.Model optional initial Model to use, maybe be set or changed later all_models : list optional list of Models to populate drop-down menu, by default all built-in and user-defined subclasses of Model are used Additional Parameters --------------------- axes_style : dictionary representing style keyword arguments to be passed through to `Axes.set(...)` data_style : dictionary representing style keyword arguments to be passed through to the matplotlib `plot()` command the plots the data points init_style : dictionary representing style keyword arguments to be passed through to the matplotlib `plot()` command the plots the initial fit line best_style : dictionary representing style keyword arguments to be passed through to the matplotlib `plot()` command the plots the best fit line **kwargs : independent variables or extra arguments, passed like `x=x` """ + _COMMON_EXAMPLES_DOC def __init__(self, data, model=None, all_models=None, axes_style={}, data_style={}, init_style={}, best_style={}, **kwargs): # Dropdown menu of all subclasses of Model, incl. user-defined. self.models_menu = Dropdown() # Dropbox API is very different between IPy 2.x and 3.x. if IPY2: if all_models is None: all_models = {m.__name__: m for m in Model.__subclasses__()} self.models_menu.values = all_models else: if all_models is None: all_models = [(m.__name__, m) for m in Model.__subclasses__()] self.models_menu.options = all_models self.models_menu.on_trait_change(self._on_model_value_change, 'value') # Button to trigger fitting. self.fit_button = Button(description='Fit') self.fit_button.on_click(self._on_fit_button_click) # Button to trigger guessing. self.guess_button = Button(description='Auto-Guess') self.guess_button.on_click(self._on_guess_button_click) # Parameter widgets are not built here. They are (re-)built when # the model is (re-)set. super(NotebookFitter, self).__init__(data, model, axes_style, data_style, init_style, best_style, **kwargs) def _repr_html_(self): display(self.models_menu) button_box = HBox() button_box.children = [self.fit_button, self.guess_button] display(button_box) for pw in self.param_widgets: display(pw) self.plot() def guess(self): guessing_successful = super(NotebookFitter, self).guess() self.guess_button.disabled = not guessing_successful def _finalize_model(self, value): first_run = not hasattr(self, 'param_widgets') if not first_run: # Remove all Parameter widgets, and replace them with widgets # for the new model. for pw in self.param_widgets: pw.close() self.models_menu.value = value self.param_widgets = [ ParameterWidgetGroup(p) for _, p in self._current_params.items() ] if not first_run: for pw in self.param_widgets: display(pw) def _finalize_params(self): for pw in self.param_widgets: pw.value = self._current_params[pw.name].value pw.min = self._current_params[pw.name].min pw.max = self._current_params[pw.name].max pw.vary = self._current_params[pw.name].vary def plot(self): clear_output(wait=True) super(NotebookFitter, self).plot() def fit(self): super(NotebookFitter, self).fit() self.plot()
def create_plot_widget(self): controller = self.controller options = self.controller.options if controller.ds is None: return xaxis = controller.defaults('xaxis') if xaxis is None: xaxis = controller.ds.independent_variables[0] yaxis = controller.defaults('yaxis') if yaxis is None: yaxis = controller.ds.independent_variables[1] center = controller.defaults('center_axes') range_x = controller.defaults('range_x') range_y = controller.defaults('range_y') xlabel = Dropdown( description='* X-Axis', values=controller.ds.independent_variables, options=controller.ds.independent_variables, value=xaxis) ylabel = Dropdown( description='* Y-Axis', values=['None'] + controller.ds.independent_variables, options=['None'] + controller.ds.independent_variables, value=yaxis) xmin = FloatText(description='* X-Min', value=range_x[0]) xmax = FloatText(description='* X-Max', value=range_x[1]) ymin = FloatText(description='* Y-Min', value=range_y[0]) ymax = FloatText(description='* Y-Max', value=range_y[1]) center_axes = Checkbox(description='Center Axes', value=center) boundaries = Checkbox(description='Draw Boundaries', value=False) plot_type = Dropdown(description='* Plot Type', values=self.widget_types, options=self.widget_types, value='Design Space (interactive)') title_widget = Text(description='Title') caption_widget = Textarea(description='Caption') included = controller.defaults('included_cases') if included is None: included = [] if isinstance(included, list) is False: included = [included] included_widget = Textarea(description='Only Cases', value=', '.join(included)) wi = VBox(children=[xlabel, ylabel, plot_type, xmin, xmax, ymin, ymax, center_axes, boundaries, title_widget, caption_widget, included_widget]) for i in [xlabel, ylabel, plot_type]: i.on_trait_change(self.update_field, 'value') plot_type.widget_container = wi button = Button(value=False, description='Add Plot') button.on_click(self.make_plot) button.xlabel = xlabel button.ylabel = ylabel button.xmin = xmin button.xmax = xmax button.ymin = ymin button.ymax = ymax button.center_axes = center_axes button.boundaries = boundaries button.plot_type = plot_type button.title = title_widget button.caption = caption_widget button.included = included_widget button.wi = wi self.title = title_widget self.caption = caption_widget self.boundaries = boundaries self.plot_type = plot_type self.xlabel = xlabel self.ylabel = ylabel self.ymin = ymin self.ymax = ymax self.xmin = xmin self.xmax = xmax add_plot = VBox(description='Add Plot', children=[wi, self.plot_data, button]) self.update_plot_widget('value', 'Design Space (Interactive)') return ('Create Plot', add_plot)
class NotebookFitter(MPLFitter): __doc__ = _COMMON_DOC + """ If IPython is available, it uses the IPython notebook's rich display to fit data interactively in a web-based GUI. The Parameters are represented in a web-based form that is kept in sync with `current_params`. All subclasses to Model, including user-defined ones, are shown in a drop-down menu. Clicking the "Fit" button updates a plot, as above, and updates the Parameters in the form to reflect the best fit. Parameters ---------- data : array-like model : lmfit.Model optional initial Model to use, maybe be set or changed later all_models : list optional list of Models to populate drop-down menu, by default all built-in and user-defined subclasses of Model are used Additional Parameters --------------------- axes_style : dictionary representing style keyword arguments to be passed through to `Axes.set(...)` data_style : dictionary representing style keyword arguments to be passed through to the matplotlib `plot()` command the plots the data points init_style : dictionary representing style keyword arguments to be passed through to the matplotlib `plot()` command the plots the initial fit line best_style : dictionary representing style keyword arguments to be passed through to the matplotlib `plot()` command the plots the best fit line **kwargs : independent variables or extra arguments, passed like `x=x` """ + _COMMON_EXAMPLES_DOC def __init__(self, data, model=None, all_models=None, axes_style={}, data_style={}, init_style={}, best_style={}, **kwargs): # Dropdown menu of all subclasses of Model, incl. user-defined. self.models_menu = Dropdown() # Dropbox API is very different between IPy 2.x and 3.x. if IPY2: if all_models is None: all_models = dict([(m.__name__, m) for m in Model.__subclasses__()]) self.models_menu.values = all_models else: if all_models is None: all_models = [(m.__name__, m) for m in Model.__subclasses__()] self.models_menu.options = all_models self.models_menu.on_trait_change(self._on_model_value_change, 'value') # Button to trigger fitting. self.fit_button = Button(description='Fit') self.fit_button.on_click(self._on_fit_button_click) # Button to trigger guessing. self.guess_button = Button(description='Auto-Guess') self.guess_button.on_click(self._on_guess_button_click) # Parameter widgets are not built here. They are (re-)built when # the model is (re-)set. super(NotebookFitter, self).__init__(data, model, axes_style, data_style, init_style, best_style, **kwargs) def _repr_html_(self): display(self.models_menu) button_box = HBox() button_box.children = [self.fit_button, self.guess_button] display(button_box) for pw in self.param_widgets: display(pw) self.plot() def guess(self): guessing_successful = super(NotebookFitter, self).guess() self.guess_button.disabled = not guessing_successful def _finalize_model(self, value): first_run = not hasattr(self, 'param_widgets') if not first_run: # Remove all Parameter widgets, and replace them with widgets # for the new model. for pw in self.param_widgets: pw.close() self.models_menu.value = value self.param_widgets = [ParameterWidgetGroup(p) for _, p in self._current_params.items()] if not first_run: for pw in self.param_widgets: display(pw) def _finalize_params(self): for pw in self.param_widgets: pw.value = self._current_params[pw.name].value pw.min = self._current_params[pw.name].min pw.max = self._current_params[pw.name].max pw.vary = self._current_params[pw.name].vary def plot(self): clear_output(wait=True) super(NotebookFitter, self).plot() def fit(self): super(NotebookFitter, self).fit() self.plot()
class CircuitBuilder(PopupWidget): """ Comprehensive circuit creation widget that has control dialogs for adding/modifying component instances as well as external ports. """ _view_name = Unicode("CircuitBuilderView", sync=True) circuit = Instance(klass=Circuit, sync=True) domains = List() _domains_by_name = Dict() components = List() _components_by_name = Dict() def __init__(self, domains, components, circuit, **kwargs): super(CircuitBuilder, self).__init__(**kwargs) if isinstance(circuit, str): circuit = Circuit(name=circuit) self.button_text = "Launch CircuitBuilder" self.description = circuit.name def _resize_inputs(el): el.set_css({"width": "100px"}) # #### make controls self.basic_controls = HorizontalContainer() self.add_component_controls = HorizontalContainer() self.add_port_controls = HorizontalContainer() self.change_component_controls = HorizontalContainer() self.change_port_controls = HorizontalContainer() # 1) basic controls self._reset_view_btn = ButtonWidget(description="Reset view") self._reset_view_btn.on_click(self.reset_view) self._circuit_name = TextWidget(description="Circuit name", value=circuit.name) self._circuit_name.on_displayed(_resize_inputs) self._rename_circ_btn = ButtonWidget(description="Rename") self._rename_circ_btn.on_click(self._rename_circuit) self._add_port_btn = ButtonWidget(description="New Port") self._add_port_btn.on_click(self.add_port_dialog) self._add_comp_btn = ButtonWidget(description="New Component") self._add_comp_btn.on_click(self.add_component_dialog) self.basic_controls.children = [ self._reset_view_btn, self._circuit_name, self._rename_circ_btn, self._add_port_btn, self._add_comp_btn, ] # 2) add component self._add_comp_type = DropdownWidget(description="ComponentType") self._add_comp_name = TextWidget(description="Component name") self._add_comp_name.on_displayed(_resize_inputs) self._add_comp_add = ButtonWidget(description="Add Component") self._add_comp_add.on_click(self._add_component) self._add_comp_back = ButtonWidget(description="Back") self._add_comp_back.on_click(self.back) self.add_component_controls.children = [ self._add_comp_type, self._add_comp_name, self._add_comp_add, self._add_comp_back, ] # 3) add port self._add_port_name = TextWidget(description="Port name") self._add_port_name.on_displayed(_resize_inputs) self._add_port_domain = DropdownWidget(description="Domain") self._add_port_domain.on_trait_change(self._update_port_directions, "value_name") self._add_port_direction = DropdownWidget(description="Direction", values={"in": "Input", "out": "Output"}) self._add_port_add = ButtonWidget(description="Add Port") self._add_port_add.on_click(self._add_port) self._add_port_back = ButtonWidget(description="Back") self._add_port_back.on_click(self.back) self.add_port_controls.children = [ self._add_port_name, self._add_port_domain, self._add_port_direction, self._add_port_add, self._add_port_back, ] # 4) change component self._mod_comp_name = TextWidget(description="Component name") self._mod_comp_name.on_displayed(_resize_inputs) self._mod_comp_rename = ButtonWidget(description="Rename") self._mod_comp_rename.on_click(self._rename_component) self._mod_comp_delete = ButtonWidget(description="Delete") self._mod_comp_delete.on_click(self.delete_selected_component) self._mod_comp_back = ButtonWidget(description="Back") self._mod_comp_back.on_click(self.back) self.change_component_controls.children = [ self._mod_comp_name, self._mod_comp_rename, self._mod_comp_delete, self._mod_comp_back, ] # 5) change port self._mod_port_name = TextWidget(description="Port name") self._mod_port_name.on_displayed(_resize_inputs) self._mod_port_rename = ButtonWidget(description="Rename") self._mod_port_rename.on_click(self._rename_port) self._mod_port_dec = ButtonWidget(description="<") self._mod_port_inc = ButtonWidget(description=">") self._mod_port_dec.on_click(self.move_selected_port_up) self._mod_port_inc.on_click(self.move_selected_port_down) self._mod_port_delete = ButtonWidget(description="Delete") self._mod_port_delete.on_click(self.delete_selected_port) self._mod_port_back = ButtonWidget(description="Back") self._mod_port_back.on_click(self.back) self.change_port_controls.children = [ self._mod_port_name, self._mod_port_rename, self._mod_port_dec, self._mod_port_inc, self._mod_port_delete, self._mod_port_back, ] # has to come at end!! self.domains = domains self.components = components self.circuit = circuit self.circuit.on_trait_change(self._handle_circuit_selection, "selected_element") self.circuit.on_trait_change(self._handle_circuit_name, "name") self.children = [ self.basic_controls, self.add_component_controls, self.add_port_controls, self.change_component_controls, self.change_port_controls, self.circuit ] self.back() # noinspection PyDocstring def reset_view(self, *_): """ Reset the pan and zoom of the circuit editor widget. """ self.circuit.zoom = (0., 0., 1.) # noinspection PyDocstring def back(self, *_): """ Quit all sub-dialogs and display the default controls for renaming the circuit. """ for c in [ self.add_component_controls, self.add_port_controls, self.change_component_controls, self.change_port_controls, ]: c.visible = False self.basic_controls.visible = True def modify_component_dialog(self, c): """ Show the control dialog for modifying a component. :param c: The component to be modified """ self.basic_controls.visible = False self.change_component_controls.visible = True self._mod_comp_name.value = c.name def modify_port_dialog(self, p): """ Show the control dialog for modifying an external port. :param p: The external port to be modified """ self.basic_controls.visible = False self.change_port_controls.visible = True self._mod_port_name.value = p.name # noinspection PyDocstring def add_port_dialog(self, *_): """ Show the dialog to add a new external port. """ self.basic_controls.visible = False self.add_port_controls.visible = True # noinspection PyDocstring def add_component_dialog(self, *_): """ Show the dialog to add a new component instance. """ self.basic_controls.visible = False self.add_component_controls.visible = True # noinspection PyDocstring,PyTypeChecker def delete_selected_component(self, *_): """ Delete the currently selected component. """ c = self.circuit.selected_element if not isinstance(c, ComponentInstance) \ or not c in self.circuit.component_instances: return self.circuit.component_instances = filter(lambda comp: comp is not c, self.circuit.component_instances) # noinspection PyTypeChecker for p in c.ports: for cc in p.connections_in + p.connections_out: cc.remove() self.circuit.selected_element = None # noinspection PyDocstring,PyTypeChecker def delete_selected_port(self, *_): """ Delete the currently selected external port. """ p = self.circuit.selected_element if not isinstance(p, Port) \ or not p in self.circuit.ports: return self.circuit.ports = filter(lambda pp: pp is not p, self.circuit.ports) # noinspection PyUnresolvedReferences for c in p.connections_in + p.connections_out: c.remove() self.circuit.selected_element = None # noinspection PyDocstring,PyTypeChecker def move_selected_port_up(self, *_): """ Move the selected port up in the overall order of external ports. """ p = self.circuit.selected_element if not isinstance(p, Port) \ or not p in self.circuit.ports: return ps = list(self.circuit.ports) ii = ps.index(p) ps.pop(ii) ii = max(1, ii) self.circuit.ports = ps[:ii - 1] + [p] + ps[ii - 1:] # noinspection PyDocstring,PyTypeChecker def move_selected_port_down(self, *_): """ Move the selected port down in the overall order of external ports. """ p = self.circuit.selected_element if not isinstance(p, Port) \ or not p in self.circuit.ports: return ps = list(self.circuit.ports) ii = ps.index(p) ps.pop(ii) self.circuit.ports = ps[:ii + 1] + [p] + ps[ii + 1:] # noinspection PyUnusedLocal def _components_changed(self, name, old, new): self._add_comp_type.values = {c.name: c.name for c in new} self._components_by_name = {c.name: c for c in new} # noinspection PyUnusedLocal def _domains_changed(self, name, old, new): self._add_port_domain.values = {d.name: d.name for d in new} self._add_port_domain.value_name = new[0].name self._domains_by_name = {d.name: d for d in new} self._update_port_directions() def _handle_circuit_selection(self): e = self.circuit.selected_element if e: if isinstance(e, Port) and e.is_ext: self.back() self.modify_port_dialog(e) return elif isinstance(e, ComponentInstance): self.back() self.modify_component_dialog(e) return self.back() def _handle_circuit_name(self): self._circuit_name.value = self.circuit.name self.description = self.circuit.name def _update_port_directions(self): d = self._domains_by_name.get(self._add_port_domain.value_name, False) if isinstance(d, Domain): self._add_port_direction.visible = d.causal def _rename_circuit(self, *_): if len(self._circuit_name.value): self.circuit.name = self._circuit_name.value # noinspection PyUnresolvedReferences def _add_component(self, *_): ctype = self._components_by_name[self._add_comp_type.value_name] cname = self._add_comp_name.value if len(cname) and not cname in self.circuit.c: new_comp = ctype.make_instance(cname) self.circuit.component_instances = self.circuit.component_instances + [new_comp] # noinspection PyUnresolvedReferences def _add_port(self, *_): d = self._domains_by_name[self._add_port_domain.value_name] direction = self._add_port_direction.value_name if not d.causal: direction = "inout" pname = self._add_port_name.value if len(pname) and not pname in self.circuit.p: newp = Port(name=pname, domain=d, direction=direction) self.circuit.ports = self.circuit.ports + [newp] def _rename_component(self, *_): c = self.circuit.selected_element if not isinstance(c, ComponentInstance): return newname = self._mod_comp_name.value if len(newname) and not newname in self.circuit.c: del self.circuit.c[c.name] c.name = newname self.circuit.c[c.name] = c def _rename_port(self, *_): p = self.circuit.selected_element if not isinstance(p, Port): return newname = self._mod_port_name.value if len(newname) and not newname in self.circuit.p: del self.circuit.p[p.name] p.name = newname self.circuit.p[p.name] = p