fit: reset of single start parameter possible

fitresult: log x added; better preview color in result
This commit is contained in:
dominik 2022-08-01 19:27:27 +02:00
parent 9aab28d593
commit 168d0fc72c
6 changed files with 99 additions and 37 deletions

View File

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'resources/_ui/fitresult.ui' # Form implementation generated from reading ui file './resources/_ui/fitresult.ui'
# #
# Created by: PyQt5 UI code generator 5.12.3 # Created by: PyQt5 UI code generator 5.15.4
# #
# WARNING! All changes made in this file will be lost! # WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
@ -100,17 +101,21 @@ class Ui_Dialog(object):
self.page = QtWidgets.QWidget() self.page = QtWidgets.QWidget()
self.page.setGeometry(QtCore.QRect(0, 0, 399, 346)) self.page.setGeometry(QtCore.QRect(0, 0, 399, 346))
self.page.setObjectName("page") self.page.setObjectName("page")
self.verticalLayout = QtWidgets.QVBoxLayout(self.page) self.gridLayout_3 = QtWidgets.QGridLayout(self.page)
self.verticalLayout.setContentsMargins(3, 3, 3, 3) self.gridLayout_3.setContentsMargins(3, 3, 3, 3)
self.verticalLayout.setSpacing(3) self.gridLayout_3.setSpacing(3)
self.verticalLayout.setObjectName("verticalLayout") self.gridLayout_3.setObjectName("gridLayout_3")
self.graphicsView = GraphicsLayoutWidget(self.page)
self.graphicsView.setObjectName("graphicsView")
self.verticalLayout.addWidget(self.graphicsView)
self.logy_box = QtWidgets.QCheckBox(self.page) self.logy_box = QtWidgets.QCheckBox(self.page)
self.logy_box.setLayoutDirection(QtCore.Qt.RightToLeft) self.logy_box.setLayoutDirection(QtCore.Qt.RightToLeft)
self.logy_box.setObjectName("logy_box") self.logy_box.setObjectName("logy_box")
self.verticalLayout.addWidget(self.logy_box) self.gridLayout_3.addWidget(self.logy_box, 2, 1, 1, 1)
self.logx_box = QtWidgets.QCheckBox(self.page)
self.logx_box.setLayoutDirection(QtCore.Qt.RightToLeft)
self.logx_box.setObjectName("logx_box")
self.gridLayout_3.addWidget(self.logx_box, 2, 0, 1, 1)
self.graphicsView = GraphicsLayoutWidget(self.page)
self.graphicsView.setObjectName("graphicsView")
self.gridLayout_3.addWidget(self.graphicsView, 0, 0, 1, 2)
self.stack.addItem(self.page, "") self.stack.addItem(self.page, "")
self.page_2 = QtWidgets.QWidget() self.page_2 = QtWidgets.QWidget()
self.page_2.setGeometry(QtCore.QRect(0, 0, 399, 346)) self.page_2.setGeometry(QtCore.QRect(0, 0, 399, 346))
@ -173,6 +178,7 @@ class Ui_Dialog(object):
self.reject_fit_checkBox.setText(_translate("Dialog", "Reject this fit")) self.reject_fit_checkBox.setText(_translate("Dialog", "Reject this fit"))
self.del_prev_checkBox.setText(_translate("Dialog", "Delete previous fits")) self.del_prev_checkBox.setText(_translate("Dialog", "Delete previous fits"))
self.logy_box.setText(_translate("Dialog", "logarithmic y axis")) self.logy_box.setText(_translate("Dialog", "logarithmic y axis"))
self.logx_box.setText(_translate("Dialog", "logarithmic x axis"))
self.stack.setItemText(self.stack.indexOf(self.page), _translate("Dialog", "Plot")) self.stack.setItemText(self.stack.indexOf(self.page), _translate("Dialog", "Plot"))
self.stack.setItemText(self.stack.indexOf(self.page_2), _translate("Dialog", "Statistics")) self.stack.setItemText(self.stack.indexOf(self.page_2), _translate("Dialog", "Statistics"))
item = self.corr_tableWidget.horizontalHeaderItem(0) item = self.corr_tableWidget.horizontalHeaderItem(0)

View File

@ -1,11 +1,9 @@
from __future__ import annotations from __future__ import annotations
from typing import List
from ...utils.text import convert from ...utils.text import convert
from ..Qt import QtWidgets, QtCore, QtGui from ..Qt import QtWidgets, QtCore, QtGui
from .._py.fitfuncwidget import Ui_FormFit from .._py.fitfuncwidget import Ui_FormFit
from ..lib.forms import FormWidget, SelectionWidget from ..lib.forms import SelectionWidget
from .fit_forms import FitModelWidget from .fit_forms import FitModelWidget
@ -83,8 +81,9 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
self.global_parameter.append(widgt) self.global_parameter.append(widgt)
self.scrollwidget.layout().addWidget(widgt) self.scrollwidget.layout().addWidget(widgt)
widgt2 = FormWidget(name=name, fixable=False, parent=self.scrollwidget2) widgt2 = ParameterSingleWidget(name=name, parent=self.scrollwidget2)
widgt2.valueChanged.connect(self.change_single_parameter) widgt2.valueChanged.connect(self.change_single_parameter)
widgt2.removeSingleValue.connect(self.change_single_parameter)
widgt2.installEventFilter(self) widgt2.installEventFilter(self)
self.scrollwidget2.layout().addWidget(widgt2) self.scrollwidget2.layout().addWidget(widgt2)
self.data_parameter.append(widgt2) self.data_parameter.append(widgt2)
@ -139,11 +138,14 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
self.data_parameter[idx].value = value self.data_parameter[idx].value = value
self.data_parameter[idx].blockSignals(False) self.data_parameter[idx].blockSignals(False)
def change_single_parameter(self, value, sender=None): def change_single_parameter(self, value: float = None, sender=None):
if sender is None: if sender is None:
sender = self.sender() sender = self.sender()
idx = self.data_parameter.index(sender) idx = self.data_parameter.index(sender)
self.data_values[self.comboBox.currentData()][idx] = value self.data_values[self.comboBox.currentData()][idx] = value
# look for global parameter values if value is reset, ie None
if value is None:
self.change_data(self.comboBox.currentIndex())
def change_single_choice(self, _, value, sender=None): def change_single_choice(self, _, value, sender=None):
if sender is None: if sender is None:
@ -259,7 +261,7 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
return data_parameter, lb, ub, is_fixed, global_p, is_linked return data_parameter, lb, ub, is_fixed, global_p, is_linked
def set_parameter(self, set_id: str | None, parameter: List[float]) -> int: def set_parameter(self, set_id: str | None, parameter: list[float]) -> int:
if set_id is None: if set_id is None:
for val, g in zip(parameter, self.global_parameter): for val, g in zip(parameter, self.global_parameter):
if isinstance(g, SelectionWidget): if isinstance(g, SelectionWidget):
@ -274,3 +276,50 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
self.change_data(self.comboBox.currentIndex()) self.change_data(self.comboBox.currentIndex())
return len(self.global_parameter) return len(self.global_parameter)
class ParameterSingleWidget(QtWidgets.QWidget):
valueChanged = QtCore.pyqtSignal(object)
removeSingleValue = QtCore.pyqtSignal()
def __init__(self, name: str, parent=None):
super().__init__(parent=parent)
self._init_ui()
self._name = name
self.label.setText(convert(name))
self.value_line.setValidator(QtGui.QDoubleValidator())
self.value_line.textChanged.connect(lambda: self.valueChanged.emit(self.value) if self.value is not None else 0)
self.reset_button.clicked.connect(lambda x: self.removeSingleValue.emit())
def _init_ui(self):
layout = QtWidgets.QHBoxLayout(self)
layout.setContentsMargins(2, 2, 2, 2)
layout.setSpacing(2)
self.label = QtWidgets.QLabel(self)
layout.addWidget(self.label)
layout.addSpacerItem(QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum))
self.value_line = QtWidgets.QLineEdit(self)
layout.addWidget(self.value_line)
self.reset_button = QtWidgets.QToolButton(self)
self.reset_button.setText('Use global')
layout.addWidget(self.reset_button)
self.setLayout(layout)
@property
def value(self) -> float:
try:
return float(self.value_line.text().replace(',', '.'))
except ValueError:
return 0.0
@value.setter
def value(self, val):
self.value_line.setText(f'{float(val):.5g}')

View File

@ -42,7 +42,7 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
self.residplot = self.graphicsView.addPlot(row=0, col=0) self.residplot = self.graphicsView.addPlot(row=0, col=0)
self.resid_graph = PlotItem(x=[], y=[], self.resid_graph = PlotItem(x=[], y=[],
symbol='o', symbolPen=None, symbolBrush=mkBrush(color=(174, 199, 232)), symbol='o', symbolPen=None, symbolBrush=mkBrush(color=(31, 119, 180)),
pen=None) pen=None)
self.resid_graph_imag = PlotItem(x=[], y=[], self.resid_graph_imag = PlotItem(x=[], y=[],
symbol='s', symbolPen=None, symbolBrush=mkBrush(color=(255, 127, 14)), symbol='s', symbolPen=None, symbolBrush=mkBrush(color=(255, 127, 14)),
@ -53,7 +53,7 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
self.fitplot = self.graphicsView.addPlot(row=1, col=0) self.fitplot = self.graphicsView.addPlot(row=1, col=0)
self.data_graph = PlotItem(x=[], y=[], self.data_graph = PlotItem(x=[], y=[],
symbol='o', symbolPen=None, symbolBrush=mkBrush(color=(174, 199, 232)), symbol='o', symbolPen=None, symbolBrush=mkBrush(color=(31, 119, 180)),
pen=None) pen=None)
self.data_graph_imag = PlotItem(x=[], y=[], self.data_graph_imag = PlotItem(x=[], y=[],
symbol='s', symbolPen=None, symbolBrush=mkBrush(color=(255, 127, 14)), symbol='s', symbolPen=None, symbolBrush=mkBrush(color=(255, 127, 14)),
@ -83,6 +83,8 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
self.graph_checkBox.stateChanged.connect(lambda x: self.graph_comboBox.setEnabled(x == QtCore.Qt.Unchecked)) self.graph_checkBox.stateChanged.connect(lambda x: self.graph_comboBox.setEnabled(x == QtCore.Qt.Unchecked))
self.logy_box.stateChanged.connect(lambda x: self.fitplot.setLogMode(y=bool(x))) self.logy_box.stateChanged.connect(lambda x: self.fitplot.setLogMode(y=bool(x)))
self.logx_box.stateChanged.connect(lambda x: self.fitplot.setLogMode(x=bool(x)))
self.residplot.setXLink(self.fitplot)
def add_graphs(self, graphs: list): def add_graphs(self, graphs: list):
self.graph_comboBox.clear() self.graph_comboBox.clear()

View File

@ -228,7 +228,7 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow):
if self.real_button.isChecked(): if self.real_button.isChecked():
item = self.real_plots[a] item = self.real_plots[a]
if item not in self.graphic.items(): if (item is not None) and item not in self.graphic.items():
self.graphic.addItem(item) self.graphic.addItem(item)
if self.error_button.isChecked(): if self.error_button.isChecked():
@ -256,12 +256,10 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow):
def set_imag_visible(self, visible: bool): def set_imag_visible(self, visible: bool):
if self.sender() == self.real_button: if self.sender() == self.real_button:
plots = self.real_plots plots = self.real_plots
other = self.imag_plots
if self.error_button.isChecked() and not visible: if self.error_button.isChecked() and not visible:
self.error_button.setChecked(False) self.error_button.setChecked(False)
else: else:
plots = self.imag_plots plots = self.imag_plots
other = self.real_plots
if visible: if visible:
func = self.graphic.addItem func = self.graphic.addItem
@ -270,8 +268,7 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow):
for a in self.active: for a in self.active:
item = plots[a] item = plots[a]
other_item = other[a] if item is not None:
if (item is not None) and (other_item is not None):
func(item) func(item)
self.show_legend() self.show_legend()

View File

@ -117,15 +117,13 @@ class FormWidget(QtWidgets.QWidget):
def _init_ui(self): def _init_ui(self):
layout = QtWidgets.QHBoxLayout(self) layout = QtWidgets.QHBoxLayout(self)
layout.setContentsMargins(2, 2, 2, 2) layout.setContentsMargins(1, 1, 1, 1)
layout.setSpacing(2) layout.setSpacing(3)
self.label = QtWidgets.QLabel(self) self.label = QtWidgets.QLabel(self)
layout.addWidget(self.label) layout.addWidget(self.label)
layout.addSpacerItem(QtWidgets.QSpacerItem(20, 20, layout.addSpacerItem(QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum))
QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Minimum))
self.vals = QtWidgets.QLineEdit(self) self.vals = QtWidgets.QLineEdit(self)
layout.addWidget(self.vals) layout.addWidget(self.vals)

View File

@ -205,10 +205,7 @@
<attribute name="label"> <attribute name="label">
<string>Plot</string> <string>Plot</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QGridLayout" name="gridLayout_3">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin"> <property name="leftMargin">
<number>3</number> <number>3</number>
</property> </property>
@ -221,10 +218,10 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>3</number> <number>3</number>
</property> </property>
<item> <property name="spacing">
<widget class="GraphicsLayoutWidget" name="graphicsView"/> <number>3</number>
</item> </property>
<item> <item row="2" column="1">
<widget class="QCheckBox" name="logy_box"> <widget class="QCheckBox" name="logy_box">
<property name="layoutDirection"> <property name="layoutDirection">
<enum>Qt::RightToLeft</enum> <enum>Qt::RightToLeft</enum>
@ -234,6 +231,19 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QCheckBox" name="logx_box">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>logarithmic x axis</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="GraphicsLayoutWidget" name="graphicsView"/>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="page_2"> <widget class="QWidget" name="page_2">