Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
0.16.4
- enh: show chi^2 annotation and toggle fit line visibility (#48, #52)
- setup: support latest python versions (#32, #46)
- setup: support latest matplotlib versions (#32, #46)
- fix: remember user's choice upon curve open (#44, #45)
Expand Down
1 change: 1 addition & 0 deletions pyjibe/fd/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def __init__(self, *args, **kwargs):
self.on_cb_rating_scheme)
self.btn_rater.clicked.connect(self.on_user_rate)
# plotting parameters
self.cb_show_fit_line.stateChanged.connect(self.on_mpl_curve_update)
self.cb_mpl_rescale_plot_x.stateChanged.connect(
self.on_mpl_curve_update)
self.cb_mpl_rescale_plot_x_min.valueChanged.connect(
Expand Down
10 changes: 10 additions & 0 deletions pyjibe/fd/main.ui
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@
<item>
<widget class="QWidget" name="plot_prefs" native="true">
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QCheckBox" name="cb_show_fit_line">
<property name="text">
<string>Show fit line</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cb_mpl_rescale_plot_x">
<property name="text">
Expand Down
15 changes: 13 additions & 2 deletions pyjibe/fd/mpl_indent.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ def __init__(self):
range(2),
label="residuals")[0]

self.ann_chi2 = self.axis_main.text(
0.98, 0.95, "", transform=self.axis_main.transAxes,
ha="right", va="top", fontsize=9,
bbox=dict(boxstyle="round,pad=0.2", fc="white", alpha=0.7))

self.canvas = FigureCanvas(self.figure)

self.canvas.draw()
Expand All @@ -67,7 +72,7 @@ def add_toolbar(self, widget):
def save_data_callback(self, filename):
self.fdist.export(filename)

def update(self, fdist, rescale_x=None, rescale_y=None):
def update(self, fdist, rescale_x=None, rescale_y=None, show_fit=True):
self.fdist = fdist
xaxis = "tip position"
yaxis = "force"
Expand Down Expand Up @@ -96,13 +101,17 @@ def update(self, fdist, rescale_x=None, rescale_y=None):

if "fit" in fdist and np.sum(fdist["fit range"]):
self.plots["residuals"].set_visible(True)
self.plots["fit"].set_visible(True)
self.plots["fit"].set_visible(show_fit)
self.plots["fit range"].set_visible(True)

self.plots["fit"].set_data(fdist["tip position"]*xscale,
fdist["fit"]*yscale)
self.plots["residuals"].set_data(fdist["tip position"]*xscale,
(fdist["fit residuals"])*yscale)

chi_sqr = fdist.fit_properties["chi_sqr"]
self.ann_chi2.set_text(rf"$\chi^2$ = {chi_sqr:.2e}")
self.ann_chi2.set_visible(True)
# fit range
fitrange = (fdist[xaxis]*xscale)[fdist["fit range"]]
fitmin = np.min(fitrange)
Expand Down Expand Up @@ -132,6 +141,8 @@ def update(self, fdist, rescale_x=None, rescale_y=None):
self.plots["residuals"].set_visible(False)
self.plots["fit"].set_visible(False)
self.plots["fit range"].set_visible(False)
self.ann_chi2.set_text("")
self.ann_chi2.set_visible(False)
self.canvas.draw()

def update_plot(self, rescale_x=None, rescale_y=None):
Expand Down
4 changes: 3 additions & 1 deletion pyjibe/fd/widget_plot_fd.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def mpl_curve_update(self, fdist):
rescale_y = (self.fd.cb_mpl_rescale_plot_y_min.value(),
self.fd.cb_mpl_rescale_plot_y_max.value())

show_fit = self.fd.cb_show_fit_line.isChecked()
self.mpl_curve.update(fdist,
rescale_x=rescale_x,
rescale_y=rescale_y)
rescale_y=rescale_y,
show_fit=show_fit)
47 changes: 47 additions & 0 deletions tests/test_fd_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,50 @@ def test_set_indentation_depth_manually_infdoublespinbox(qtbot):
qtbot.keyClicks(war.tab_fit.sp_range_1, text_entered)
assert war.tab_fit.sp_range_1.value() == resulting_value
main_window.close()


def test_show_fit_line_toggle(qtbot):
"""Toggle cb_show_fit_line hides/shows the fit line on the plot."""
main_window = pyjibe.head.PyJibe()
qtbot.addWidget(main_window)
main_window.load_data(files=make_directory_with_data(2))
war = main_window.subwindows[0].widget()
war.cb_autosave.setChecked(0)
war.tab_preprocess.set_preprocessing(["compute_tip_position"])
war.tab_fit.cb_weight_cp.setCheckState(QtCore.Qt.CheckState.Unchecked)
war.on_tab_changed()

mpl = war.widget_plot_fd.mpl_curve
# fit line should be visible by default
assert mpl.plots["fit"].get_visible()

# uncheck the toggle — fit line should disappear
war.cb_show_fit_line.setChecked(False)
war.on_mpl_curve_update()
assert not mpl.plots["fit"].get_visible()

# re-check — fit line should reappear
war.cb_show_fit_line.setChecked(True)
war.on_mpl_curve_update()
assert mpl.plots["fit"].get_visible()
main_window.close()


def test_chi_sqr_annotation_shown_after_fit(qtbot):
"""Chi^2 annotation should be visible after a successful fit."""
main_window = pyjibe.head.PyJibe()
qtbot.addWidget(main_window)
main_window.load_data(files=make_directory_with_data(2))
war = main_window.subwindows[0].widget()
war.cb_autosave.setChecked(0)
war.tab_preprocess.set_preprocessing(["compute_tip_position"])
war.tab_fit.cb_weight_cp.setCheckState(QtCore.Qt.CheckState.Unchecked)
war.on_tab_changed()

mpl = war.widget_plot_fd.mpl_curve
assert mpl.ann_chi2.get_visible()
text = mpl.ann_chi2.get_text()
assert text.startswith(r"$\chi^2$")
chi2_value = float(text.split("=")[1].strip())
assert 0.0 <= chi2_value <= 1.0
main_window.close()
Loading