lsqfitgui documentation¶
Quick start¶
Install¶
To install the package and its dependencies, clone the repository and run the following command in the repository root directory
pip install --upgrade numpy scipy
pip install [-e] .
or equivalently (let pip do the cloning)
pip install --upgrade numpy scipy
pip install git+https://github.com/ckoerber/lsqfit-gui@master
(lsqfit
and gvar
require numpy
and scipy
as build dependencies. Installing these packages before install gvar
ensures a smooth installation.)
Usage¶
The GUI can be started either:
directly from another python script
# some_script.py
from lsqfit import nonlinear_fit
from lsqfitgui import run_server
...
fit = nonlinear_fit(data, fcn=fcn, prior=prior)
run_server(fit)
or over the entry point, which requires a
gvar
pickled fit and an import path to the fit function. As an example, first export the fit running the following script,
#other_script.py
import gvar as gv
from lsqfit import nonlinear_fit
def fcn(x, p):
y = ...
return y
...
fit = nonlinear_fit(data, fcn=fcn, prior=prior)
gv.dump(fit, "fit.p")
and run the GUI with
lsqfitgui [--function other_script.py:fcn] fit.p
Advanced usage¶
See also the examples/
folder and documentation.
Examples¶
Tip
In the examples/
directory, we provide different examples which can be started by running
python example/{script}.py
and visiting http://localhost:8000.
First steps¶
Launching the dashboard via script¶
In the most simple case, lsqfitgui
requires a lsqfit.nonlinear_fit
object as its only argument.
An example script capable of launching the GUI for a simple quadratic fit model is given by
#my_fit.py
import numpy as np
from lsqfit import nonlinear_fit
from gvar import gvar
from lsqfitgui import run_server
x = np.linspace(0, 1, 10)
# first argument is the mean, second the standard deviation
y = gvar(x**2, np.ones(len(x)) * 0.1)
def fcn(x, p):
return p["a0"] + p["a1"] * x + p["a2"] * x ** 2
prior = {"a0": gvar(0, 2), "a1": gvar(0, 2), "a2": gvar(0, 2)}
fit = nonlinear_fit(data=(x, y), fcn=fcn, prior=prior)
run_server(fit)
Running python my_fit.py
launches the dashboard locally at http://localhost:8000.
This GUI allows for varying prior parameters (mean and standard deviations) and inspecting their effects on the fit.
Launching the dashboard via CLI¶
Additionally, for a dumped fit object
from gvar import dump
...
dump(fit, outputfile="fit.p")
it is possible to launch the GUI by running
lsqfitgui --function my_fit.py:fcn fit.p
Meta parameters¶
For some fits, you may not only want to vary the prior parameters but also entirely change the model (or data).
This is done by the providing a fit_setup_function
and respective configuration to the lsqfitgui.run_server()
method.
#my_fit.py
import numpy as np
from lsqfit import nonlinear_fit
from gvar import gvar
from lsqfitgui import run_server
x = np.linspace(0, 1, 10)
y = gvar(x**2, np.ones(len(x)) * 0.1)
# Modify the fit function to be flexible in the number of parameters
def fcn(x, p):
return sum([p[f"a{n}"] * x **n for n in range(len(p))])
def generate_fit(n_order=2):
prior = {f"a{n}": gvar(0, 2) for n in range(n_order+1)}
return nonlinear_fit(data=(x, y), fcn=fcn, prior=prior)
run_server(fit_setup_function=generate_fit)
Running this script will launch the same dashboard as before.
To update the meta parameter n_order
in the GUI, we have to provide an initial value
fit_setup_kwargs = {"n_order": 2}
and parameters to set up a form
meta_config = [{"name": "n_order", "type": "number", "min": 1, "max": 10, "step": 1}]
so that the actual run command is
run_server(
fit_setup_function=generate_fit,
fit_setup_kwargs=fit_setup_kwargs,
meta_config=meta_config
)
Note
You can provide more than just one meta setup parameter of arbitrary type.
These parameters can have any type allowed to be parsed from HTML widgets.
You can find more details about allowed meta_config
parameters at the dcc.Input
documentation.
Note that the id
of the widget is automatically provided by the name
keyword from the meta_config
dictionary, which must match the fit_setup_kwargs
keyword and the generate_fit
keyword.).
Adding plots¶
If you want to add plots, you can use the additional_plots
keyword.
The default options must provide a name and a function which takes a fit object and returns a plotly.graph_objects.Figure
from plotly.graph_objects import Figure
def plot_fcn(fit):
fig = Figure()
...
return fig
additional_plots = [{"name": "My plot", "fcn": plot_fcn}]
run_server(
fit_setup_function=generate_fit,
fit_setup_kwargs=fit_setup_kwargs,
meta_config=meta_config,
additional_plots=additional_plots,
)
This method adds plots to the already existing plots container.
For convenience, we have also added methods for creating figures directly from gvars
.
For example, if you want to add a custom function my_func
to the plot, you can add the lines
from lsqfitgui import plot_gvar
def my_func(x, p):
yy = ...
return yy
def plot_my_func(fit):
y_fit = my_func(fit.x, fit.p)
return plot_gvar(fit.x, y_fit, kind="errorband")
additional_plots = [{"name": "My function", "fcn": plot_log_log}]
Additionally, if you have a function that already takes x
and p
arguments as the fit function of the nonlinear_fit
object, you can use
from lsqfitgui import wrap_plot_gvar
@wrap_plot_gvar(kind="band")
def plot_my_func_wrapped(x, p):
return my_func(x, p)
additional_plots = [{
"name": "My function",
"fcn": plot_my_func_wrapped,
"description": "This figure displays my function.", # optional
}]
which does effectively the same thing.
Additional kwargs¶
The additional_plots
list also allows dictionaries with more keyword arguments.
Allowed are
name (str): The name presented in the tabs.
fcn (Callable[[nonlinear_fit], Figure]): The function used to generate the plot. Must take a plot and kwargs as an input.
kwargs (Dict[str, Any]): A dictionary passed to the provided function.
static_plot_gvar (Dict[str, Any]): Static data passed to
lsqfitgui.plot_gvar()
added to the same figure (i.e., to also plot data as an comparison).
For example, one setup could be
x_data, y_data = ... # some static values to compare against
additional_plots = [{
"name": "My function",
"fcn": plot_my_func_wrapped,
"static_plot_gvar": {
"x": x_data,
"y": y_data,
"kind": "errorbars",
"scatter_kwargs": {"name": "Data"} # Is passed to go.Scatter
}
}]
Further usage¶
See also the example
directory or API docs.
API: lsqfitgui¶
run_server
¶
- run_server(fit=None, name='Lsqfit GUI', fit_setup_function=None, fit_setup_kwargs=None, meta_config=None, use_default_content=True, get_additional_content=None, additional_plots=None, run_app=True, debug=True, host='localhost', port=8000)¶
Initialize the GUI and start the dash app.
Requires either a fit object or a fit_setup_function.
- Parameters
fit (Optional[lsqfit.nonlinear_fit]) – Non-linear fit object.
name (str) – Name of the app displayed as title and browser tab title.
fit_setup_function (Optional[Callable[[Any], lsqfit.nonlinear_fit]]) – Function which returns a non-linear fit object. Its keywords are provided by fit_setup_kwargs.
fit_setup_kwargs (Optional[Dict]) – Initial kwargs which are passed to the fit_setup_function for creating the first fit object.
meta_config (Optional[List[Dict]]) – Configuration for the fit_setup_kwargs represented in the GUI. These must match dcc.Input arguments.
use_default_content (Optional[bool]) – Add default elements like the function documentation and plot tabs to the GUI.
get_additional_content (Optional[Callable[[lsqfit.nonlinear_fit], dash.html.Base.Base]]) – Function used to determine dynamic content depending on fit results.
additional_plots (Optional[Dict[str, Callable]]) – List of dictionaries specifying plots rendered in the tab element. Must contain at least the name: str and fcn:Callable[[nonlinear_fit], Figure] items. This populates
FitGUI.plots
. See also thelsqfitgui.frontend.content.DEFAULT_PLOTS
.run_app (bool) – Call run server on the dash app.
debug (bool) – Run the dash app in debug mode. Only used if run_app=True.
host (str) – The hosting address of the dash app. Only used if run_app=True.
port (int) – The port of the dash app. Only used if run_app=True.
- Return type
Example
The most basic example just requires a nonlinear_fit object:
fit = lsqfit.nonlinear_fit(data, fcn=fcn, prior=prior) app = run_server(fit)
More sophisticated examples, where also meta arguments are used, are:
def generate_fit(n_exp=3): ... return lsqfit.nonlinear_fit(data, fcn=fcn, prior=prior) fit_setup_kwargs = {"n_exp": 3} meta_config = [{"name": "n_exp", "type": "number", "min": 1, "max": 10, "step": 1}] fit_gui = run_server( fit_setup_function=generate_fit, fit_setup_kwargs=fit_setup_kwargs, meta_config=meta_config )
plot_gvar
¶
- plot_gvar(x, y, fig=None, kind='band', add_log_menu=False, scatter_kwargs=None)¶
Plot gvars as go.Figures including their uncertainties.
- Parameters
x (Union[numpy.ndarray, Dict[str, numpy.ndarray]]) – The independent variable. Can be either an array or a dictionary of arrays where keys must match the keys of the dependent variable. If
kind="band"
, tries to interpolate the values.y (gvar._bufferdict.BufferDict) – The dependent variable. If it is a dictionary of gvar arrays, the figure will contain several subfigures.
fig (Optional[plotly.graph_objs._figure.Figure]) – Figure to add traces to. If not specified, creates a new figure.
kind (str) – Either
"band"
or"errorbars"
.add_log_menu (bool) – Add a menu to switch from a linear to a log scale. Only available if
y
is not a dictionary.scatter_kwargs (Optional[Dict]) – Keyword arguments passed to
go.Scatter
.
- Return type
plotly.graph_objs._figure.Figure
wrap_plot_gvar
¶
- wrap_plot_gvar(kind='band', add_log_menu=False, scatter_kwargs=None)¶
Wraps functions taking
x
andp
arguments such that they can be used by thelsqfitgui.FitGUI.plots
to generate plots of gvars.- Parameters
kind (str) – Allowed values:
"band"
,"errorbar"
. Returned figure will contain error bars or error bands.add_log_menu (bool) – Should the returned figure have a menu allowing to change from regular to log y-axis?
scatter_kwargs (Optional[Dict]) – Keyword arguments passed to
go.Scatter()
.
- Return type
Callable[[lsqfit.nonlinear_fit], plotly.graph_objs._figure.Figure]
Example
The code below presents how to use the wrapper to add new plots to the GUI:
def fcn(x, p): yy = ... return yy def plot_fcn(fit): yy = fcn(fit.x, fit.p) return plot_gvar(fit.x, yy, kind="band") @wrap_plot_gvar(kind="band") def wrapped_fcn(x, p): return fcn(x, p) gui.plots.append({"name": "Fcn results", "fcn": wrapped_fcn})
Both functions, wrapped_fcn and plot_fcn will produce the same plot when added to the gui.
FitGUI
¶
- class FitGUI(fit=None, fit_setup_function=None, fit_setup_kwargs=None, meta_config=None, use_default_content=True)¶
Class which initializes the dashboard.
Initialize the fit gui.
You must either provide a fit object or a fit_setup_function function to initialize this class. Note that this dose not create a
Dash
app; the app is created by callingFitGUI.setup_app()
(which is implicitly called byFitGUI.run_server()
).- Parameters
fit (Optional[lsqfit.nonlinear_fit]) – Non-linear fit object.
fit_setup_function (Optional[Callable]) – Function which returns a non-linear fit object. Its keywords are provided by fit_setup_kwargs.
fit_setup_kwargs (Optional[Dict]) – Initial kwargs which are passed to the fit_setup_function for creating the first fit object.
meta_config (Optional[List[Dict]]) –
Configuration for the fit_setup_kwargs represented in the GUI. These must match dcc.Input arguments.
use_default_content (bool) – Add default elements like the function documentation and plot tabs to the GUI.
Example
The most basic example just requires a nonlinear_fit object:
fit = lsqfit.nonlinear_fit(data, fcn=fcn, prior=prior) gui = FitGUI(fit)
More sophisticated examples, where also meta arguments are used, are:
from dash import Dash def generate_fit(n_exp=3): ... return lsqfit.nonlinear_fit(data, fcn=fcn, prior=prior) fit_setup_kwargs = {"n_exp": 3} meta_config = [{"name": "n_exp", "type": "number", "min": 1, "max": 10, "step": 1}] gui = FitGUI( fit_setup_function=generate_fit, fit_setup_kwargs=fit_setup_kwargs, meta_config=meta_config ) fit_gui.run_server(host=host, debug=debug, port=port)
- property app: dash.dash.Dash¶
Return plotly dash app.
- property fit: lsqfit.nonlinear_fit¶
Return current fit object.
- get_additional_content: Callable[[lsqfit.nonlinear_fit], dash.html.Base.Base]¶
Function used to determine dynamic content depending on fit results.
- property initial_fit: lsqfit.nonlinear_fit¶
Return fit object used to initialize the app.
- property layout: dash.html.Base.Base¶
Return the current layout.
- name: str¶
Name of the app displayed as title and browser tab title.
- plots: List[Dict[str, Any]]¶
List of dictionaries specifying plots rendered in the tab element. Must contain at least the name: str and fcn:Callable[[nonlinear_fit], Figure] items.
Example
Plot the fit results:
def plot_fcn(fit): yy = fit.fcn(fit.x, fit.p) return plot_gvar(fit.x, yy, kind="band") gui.plots.append({"name": "Fit results", "fcn": plot_fcn})
Allowed keywords are
name (str): The name presented in the tabs.
fcn (Callable[[nonlinear_fit], Figure]): The function used to generate the plot. Must take a plot and kwargs as an input.
description (str): Text displayed below figure (can contain latex using).
kwargs (Dict[str, Any]): A dictionary passed to the above function.
static_plot_gvar (Dict[str, Any]): Static data passed to
plot_gvar()
added to the same figure (i.e., to also plot data as an comparison).
See also the
lsqfitgui.frontend.content.DEFAULT_PLOTS
.
- run_server(*args, **kwargs)¶
Wrapper to self.app.run_server.
- setup_app(app=None)¶
Initialize the dash app.
Sets up layout and callbacks and create a
Dash
instance if not provided.- Parameters
app (Optional[dash.dash.Dash]) – The dash app which runs the server. If provided, requires to manually set up style sheets, scripts and assets.
Raises RuntimeError if app already set up.
About¶
Graphical user interface for performing Bayesian Inference (bayesian fits) using lsqfit
and dash
.
This module aims at making complicated analysis projects
more intuitive
accessible to a broader range of people
easily shareable
and thus effectively increasing transparency.