Source code for squap

# starts off by creating an instance of main_window, containing a plot widget.
from typing import Callable, Iterable       # required for docs

from . import widgets
from .widgets import (MainWindow, FigWidget, TableManager, SubplotWidget, InputTable, Box, PlotCurve, ErrorbarCurve,
                      TextCurve, InfLine, ImageCurve, GridCurve)
from .variables import Variables
from .customisation import get_font, get_gradient, get_cmap, cmap_to_colors
from .helper_funcs import ColorType, ColorsType

import functools        # for copy_docstring decorator
import inspect

from pyqtgraph import setConfigOption
from PySide6.QtCore import QTimer


__all__ = [
    "widgets", "ColorType", "ColorsType",       # things not in __init__.pyi
    "var", "plot", "scatter", "errorbar", "set_xlim", "set_ylim", "xlim", "ylim", "legend", "set_title", "lock_zoom", "subplots",
    "remove_item", "get_gradient", "get_cmap", "inf_dline", "inf_hline", "inf_vline", "grid", "plot_text", "merge_plots", "set_interval",
    "on_refresh", "on_mouse_click", "on_mouse_move", "get_mouse_pos", "on_key_press", "add_slider", "add_checkbox", "add_inputbox", "add_button",
    "add_dropdown", "add_rate_slider", "link_boxes", "add_tab", "set_active_tab", "rename_tab", "on_tab_change", "get_all_boxes", "display_fps", "resize", "benchmark", "set_input_width",
    "set_input_partition", "is_alive", "refresh", "show_window", "show", "clear", "export", "export_video", "start_recording", "get_font",
    "cmap_to_colors", "enable_autoscale", "disable_autoscale", "enable_autopan", "disable_autopan",
    "make_3D", "scatter_3D", "add_grid_3D", "add_grids_3D", "set_zoom_rate_3D", "set_camera",
    "align_camera"
]

_window = None
_input_table = None
_table_manager = None
_plot_widget_3D = None
var = Variables()


def _copy_docstring(method):
    def decorator(func):
        original_name = func.__name__  # save before update_wrapper overwrites it
        original_module = func.__module__
        sig = inspect.signature(method)
        params = list(sig.parameters.values())
        if params and params[0].name == 'self':
            params = params[1:]
        new_sig = sig.replace(parameters=params)
        functools.update_wrapper(func, method)
        if hasattr(func, '__wrapped__'):
            del func.__wrapped__
        func.__name__ = original_name  # restore
        func.__module__ = original_module
        func.__signature__ = new_sig
        return func
    return decorator


def get_window() -> MainWindow:
    global _window
    if _window is None:
        _window = widgets.MainWindow(var)
    return _window


def get_input_table() -> InputTable:
    global _input_table
    if _input_table is None:
        if get_window().table_manager.first_input_table:     # it is possible to init table widget without this function
            _input_table = get_window().table_manager.first_input_table
        else:
            _input_table = get_window().init_first_tab()
    return _input_table


def get_table_manager():
    """Makes sure that when a function from table_manager is called, the input table is initialised."""
    global _table_manager
    if _table_manager is None:
        get_input_table()
        _table_manager = get_window().table_manager
    return _table_manager


def get_plot_3D():
    """Makes sure that when a function associated to 3D plots, a 3D plot widget gets initialised."""
    global _plot_widget_3D
    if _plot_widget_3D is None:
        _plot_widget_3D = get_window().fig_widget.make_3D()
    return _plot_widget_3D


# <editor-fold desc="wrapped functions">
[docs] @_copy_docstring(widgets.SubplotWidget.plot) def plot(*args, **kwargs): return get_window().fig_widget.plot_widget.plot(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.scatter) def scatter(*args, **kwargs): return get_window().fig_widget.plot_widget.scatter(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.errorbar) def errorbar(*args, **kwargs): return get_window().fig_widget.plot_widget.errorbar(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.inf_dline) def inf_dline(*args, **kwargs): return get_window().fig_widget.plot_widget.inf_dline(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.inf_hline) def inf_hline(*args, **kwargs): return get_window().fig_widget.plot_widget.inf_hline(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.inf_vline) def inf_vline(*args, **kwargs): return get_window().fig_widget.plot_widget.inf_vline(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.grid) def grid(*args, **kwargs): return get_window().fig_widget.plot_widget.grid(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.plot_text) def plot_text(*args, **kwargs): return get_window().fig_widget.plot_widget.plot_text(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.imshow) def imshow(*args, **kwargs): return get_window().fig_widget.plot_widget.imshow(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.set_xlim) def set_xlim(*args, **kwargs): return get_window().fig_widget.plot_widget.set_xlim(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.set_ylim) def set_ylim(*args, **kwargs): return get_window().fig_widget.plot_widget.set_ylim(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.xlim) def xlim(*args, **kwargs): return get_window().fig_widget.plot_widget.xlim(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.ylim) def ylim(*args, **kwargs): return get_window().fig_widget.plot_widget.ylim(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.set_xlabel) def set_xlabel(*args, **kwargs): return get_window().fig_widget.plot_widget.set_xlabel(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.set_ylabel) def set_ylabel(*args, **kwargs): return get_window().fig_widget.plot_widget.set_ylabel(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.show_grid) def show_grid(*args, **kwargs): return get_window().fig_widget.plot_widget.show_grid(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.disable_flicker) def disable_flicker(*args, **kwargs): return get_window().fig_widget.plot_widget.disable_flicker(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.enable_autoscale) def enable_autoscale(*args, **kwargs): return get_window().fig_widget.plot_widget.enable_autoscale(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.disable_autoscale) def disable_autoscale(*args, **kwargs): return get_window().fig_widget.plot_widget.disable_autoscale(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.enable_autopan) def enable_autopan(*args, **kwargs): return get_window().fig_widget.plot_widget.enable_autopan(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.disable_autopan) def disable_autopan(*args, **kwargs): return get_window().fig_widget.plot_widget.disable_autopan(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.legend) def legend(*args, **kwargs): return get_window().fig_widget.plot_widget.legend(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.set_title) def set_title(*args, **kwargs): return get_window().fig_widget.plot_widget.set_title(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.lock_zoom) def lock_zoom(*args, **kwargs): return get_window().fig_widget.plot_widget.lock_zoom(*args, **kwargs)
[docs] @_copy_docstring(widgets.FigWidget.create_subplots) def subplots(*args, **kwargs): return get_window().fig_widget.create_subplots(*args, **kwargs)
[docs] @_copy_docstring(widgets.FigWidget.remove_item) def remove_item(*args, **kwargs): return get_window().fig_widget.remove_item(*args, **kwargs)
[docs] @_copy_docstring(widgets.FigWidget.merge_plots) def merge_plots(*args, **kwargs): return get_window().fig_widget.merge_plots(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.set_interval) def set_interval(*args, **kwargs): return get_window().set_interval(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.is_alive) def is_alive(): return get_window().is_alive()
[docs] @_copy_docstring(widgets.TableManager.add_slider) def add_slider(*args, **kwargs): return get_table_manager().add_slider(*args, **kwargs)
[docs] @_copy_docstring(widgets.TableManager.add_checkbox) def add_checkbox(*args, **kwargs): return get_table_manager().add_checkbox(*args, **kwargs)
[docs] @_copy_docstring(widgets.TableManager.add_inputbox) def add_inputbox(*args, **kwargs): return get_table_manager().add_inputbox(*args, **kwargs)
[docs] @_copy_docstring(widgets.TableManager.add_button) def add_button(*args, **kwargs): return get_table_manager().add_button(*args, **kwargs)
[docs] @_copy_docstring(widgets.TableManager.add_dropdown) def add_dropdown(*args, **kwargs): return get_table_manager().add_dropdown(*args, **kwargs)
[docs] @_copy_docstring(widgets.TableManager.add_rate_slider) def add_rate_slider(*args, **kwargs): return get_table_manager().add_rate_slider(*args, **kwargs)
[docs] @_copy_docstring(widgets.TableManager.add_color_picker) def add_color_picker(*args, **kwargs): return get_table_manager().add_color_picker(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.on_mouse_click) def on_mouse_click(*args, **kwargs): return get_window().fig_widget.plot_widget.on_mouse_click(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.on_mouse_move) def on_mouse_move(*args, **kwargs): return get_window().fig_widget.plot_widget.on_mouse_move(*args, **kwargs)
[docs] @_copy_docstring(widgets.SubplotWidget.get_mouse_pos) def get_mouse_pos(*args, **kwargs): return get_window().fig_widget.plot_widget.get_mouse_pos(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.on_key_press) def on_key_press(*args, **kwargs): return get_window().on_key_press(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.add_table) def add_tab(*args, **kwargs): return get_window().add_table(*args, **kwargs)
@_copy_docstring(widgets.TableManager.rename_tab) def rename_tab(*args, **kwargs): return get_table_manager().rename_tab(*args, **kwargs)
[docs] @_copy_docstring(widgets.TableManager.set_active_tab) def set_active_tab(*args, **kwargs): return get_table_manager().set_active_tab(*args, **kwargs)
[docs] @_copy_docstring(widgets.TableManager.get_active_tab) def get_active_tab(*args, **kwargs): return get_table_manager().get_active_tab(*args, **kwargs)
@_copy_docstring(widgets.TableManager.get_all_tabs) def get_all_tabs(): return get_table_manager().get_all_tabs()
[docs] @_copy_docstring(widgets.TableManager.on_tab_change) def on_tab_change(*args, **kwargs): return get_table_manager().on_tab_change(*args, **kwargs)
[docs] @_copy_docstring(widgets.TableManager.get_all_boxes) def get_all_boxes(): return get_table_manager().get_all_boxes()
@_copy_docstring(widgets.TableManager.get_current_row) def get_current_row(): return get_table_manager().get_current_row() @_copy_docstring(widgets.TableManager.link_boxes) def link_boxes(*args, **kwargs): return get_table_manager().link_boxes(*args, **kwargs)
[docs] @_copy_docstring(widgets.TableManager.set_input_partition) def set_input_partition(*args, **kwargs): return get_table_manager().set_input_partition(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.resize_window) def resize(*args, **kwargs): return get_window().resize_window(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.size) def size(): return get_window().size()
[docs] @_copy_docstring(widgets.MainWindow.set_input_width) def set_input_width(*args, **kwargs): return get_window().set_input_width(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.display_fps) def display_fps(*args, **kwargs): return get_window().display_fps(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.benchmark) def benchmark(*args, **kwargs): return get_window().benchmark(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.refresh) def refresh(*args, **kwargs): return get_window().refresh(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.show_window) def show_window(): return get_window().show_window()
[docs] @_copy_docstring(widgets.MainWindow.on_refresh) def on_refresh(*args, **kwargs): return get_window().on_refresh(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.start) def show(): return get_window().start()
def close_window(): """Closes the window.""" return get_window().close()
[docs] @_copy_docstring(widgets.MainWindow.clear) def clear(): return get_window().clear()
[docs] @_copy_docstring(widgets.MainWindow.export) def export(*args, **kwargs): return get_window().export(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.export_video) def export_video(*args, **kwargs): return get_window().export_video(*args, **kwargs)
[docs] @_copy_docstring(widgets.MainWindow.start_recording) def start_recording(*args, **kwargs): return get_window().start_recording(*args, **kwargs)
[docs] @_copy_docstring(widgets.FigWidget.make_3D) def make_3D(*args, **kwargs): return get_window().fig_widget.make_3D(*args, **kwargs)
[docs] @_copy_docstring(widgets.plot_widget_3D.SubplotWidget3D.set_zoom_rate) def set_zoom_rate_3D(*args, **kwargs): return get_plot_3D().set_zoom_rate(*args, **kwargs)
[docs] @_copy_docstring(widgets.plot_widget_3D.SubplotWidget3D.add_grid) def add_grid_3D(*args, **kwargs): return get_plot_3D().add_grid(*args, **kwargs)
[docs] @_copy_docstring(widgets.plot_widget_3D.SubplotWidget3D.add_grids) def add_grids_3D(*args, **kwargs): return get_plot_3D().add_grids(*args, **kwargs)
[docs] @_copy_docstring(widgets.plot_widget_3D.SubplotWidget3D.scatter) def scatter_3D(*args, **kwargs): return get_plot_3D().scatter(*args, **kwargs)
[docs] @_copy_docstring(widgets.plot_widget_3D.SubplotWidget3D.set_camera) def set_camera(*args, **kwargs): return get_plot_3D().set_camera(*args, **kwargs)
[docs] @_copy_docstring(widgets.main_window.MainWindow.align_camera) def align_camera(*args, **kwargs): get_plot_3D() # make sure 3D plot exists get_input_table() # make sure input tab exists return get_window().align_camera(*args, **kwargs)
# </editor-fold> def enable_numba(enable: bool = True): """Enable numba. Can be a little faster, but takes longer to initialize. """ setConfigOption('useNumba', enable) def on_next_refresh(func: Callable): # todo: only works in eventloop, not in show_window style. """Calls a function upon next refresh only. """ QTimer.singleShot(0, func)