Skip to content

Commit 83e9b64

Browse files
committed
fix: ValueError when trying to compute contour spacing; coloring scatter plot by feature did not work; search path in session should not be filename
1 parent a23834c commit 83e9b64

File tree

6 files changed

+99
-32
lines changed

6 files changed

+99
-32
lines changed

CHANGELOG

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
2.1.2
2+
- fix: ValueError when trying to compute contour spacing, because no
3+
datasets are selected for a plot
4+
- fix: coloring scatter plot by feature did not work when the feature
5+
contains nan values
6+
- fix: search path in session should not be filename but its
7+
directory
18
2.1.1
29
- fix: include private datasets when searching with DCOR API Key
310
- fix: remove UI option to compute Young's modulus for reservoir data

shapeout2/gui/analysis/ana_plot.py

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -337,31 +337,32 @@ def _set_contour_spacing_auto(self, axis_x=None, axis_y=None):
337337
return
338338
else:
339339
self.setEnabled(True)
340-
spacings_xy = []
341-
for axis, scaleCombo in zip([axis_x, axis_y],
342-
[self.comboBox_scale_x,
343-
self.comboBox_scale_y]):
344-
if axis is None:
345-
# nothing to do
346-
spacings_xy.append(None)
347-
else:
348-
# determine good approximation
349-
dslist, _ = self.pipeline.get_plot_datasets(
350-
self.current_plot.identifier)
351-
spacings = []
352-
for ds in dslist:
353-
spa = ds.get_kde_spacing(
354-
a=ds[axis],
355-
feat=axis,
356-
scale=scaleCombo.currentData(),
357-
method=dclab.kde_methods.bin_width_percentile,
358-
)
359-
spacings.append(spa)
360-
spacings_xy.append(np.min(spacings))
361-
spacing_x, spacing_y = spacings_xy
362-
# sets the limits before setting the value
363-
self._set_contour_spacing(spacing_x=spacing_x,
364-
spacing_y=spacing_y)
340+
dslist, _ = self.pipeline.get_plot_datasets(
341+
self.current_plot.identifier)
342+
if dslist:
343+
spacings_xy = []
344+
for axis, scaleCombo in zip([axis_x, axis_y],
345+
[self.comboBox_scale_x,
346+
self.comboBox_scale_y]):
347+
if axis is None:
348+
# nothing to do
349+
spacings_xy.append(None)
350+
else:
351+
# determine good approximation
352+
spacings = []
353+
for ds in dslist:
354+
spa = ds.get_kde_spacing(
355+
a=ds[axis],
356+
feat=axis,
357+
scale=scaleCombo.currentData(),
358+
method=dclab.kde_methods.bin_width_percentile,
359+
)
360+
spacings.append(spa)
361+
spacings_xy.append(np.min(spacings))
362+
spacing_x, spacing_y = spacings_xy
363+
# sets the limits before setting the value
364+
self._set_contour_spacing(spacing_x=spacing_x,
365+
spacing_y=spacing_y)
365366

366367
@property
367368
def current_plot(self):

shapeout2/gui/main.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,12 +550,13 @@ def on_action_import_filter(self):
550550
# update UI
551551
self.reload_pipeline()
552552

553-
def on_action_open(self):
553+
def on_action_open(self, path=None):
554554
if self.pipeline.slots or self.pipeline.filters:
555555
if not self.on_action_clear():
556556
return
557-
path, _ = QtWidgets.QFileDialog.getOpenFileName(
558-
self, 'Open session', '', 'Shape-Out 2 session (*.so2)')
557+
if path is None:
558+
path, _ = QtWidgets.QFileDialog.getOpenFileName(
559+
self, 'Open session', '', 'Shape-Out 2 session (*.so2)')
559560
if path:
560561
search_paths = []
561562
while True:

shapeout2/gui/pipeline_plot.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,10 @@ def add_scatter(plot_item, plot_state, rtdc_ds, slot_state):
478478
feat -= sca["hue min"]
479479
feat /= sca["hue max"] - sca["hue min"]
480480
for f in feat:
481-
brush.append(cmap.mapToQColor(f))
481+
if np.isnan(f):
482+
brush.append(pg.mkColor("#FF0000"))
483+
else:
484+
brush.append(cmap.mapToQColor(f))
482485
elif sca["marker hue"] == "dataset":
483486
alpha = int(sca["marker alpha"] * 255)
484487
colord = pg.mkColor(slot_state["color"])

shapeout2/session.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ def save_session(path, pipeline):
192192
if slot.format == "hdf5":
193193
# search path
194194
try:
195-
rel = os.path.relpath(slot.path, path.parent)
195+
rel = os.path.relpath(slot.path.parent, path.parent)
196196
except (OSError, ValueError):
197197
rel = "."
198198
search_paths[slot.identifier] = rel

tests/test_gui_plotting.py

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
from shapeout2 import pipeline, session
99

1010

11+
datapath = pathlib.Path(__file__).parent / "data"
12+
13+
1114
@pytest.fixture(autouse=True)
1215
def run_around_tests():
1316
# Code that will run before your test, for example:
@@ -18,6 +21,45 @@ def run_around_tests():
1821
session.clear_session()
1922

2023

24+
def test_handle_axis_selection_empty_plot(qtbot):
25+
"""User did not add a dataset to a plot and starts changing plot params"""
26+
mw = ShapeOut2()
27+
qtbot.addWidget(mw)
28+
29+
# add a dataslot
30+
path = datapath / "calibration_beads_47.rtdc"
31+
mw.add_dataslot(paths=[path])
32+
33+
# add a plot
34+
plot_id = mw.add_plot()
35+
36+
assert len(mw.pipeline.slot_ids) == 1, "we added that"
37+
assert len(mw.pipeline.filter_ids) == 1, "automatically added"
38+
assert len(mw.pipeline.plot_ids) == 1, "we added that"
39+
40+
# activate analysis view
41+
pe = mw.block_matrix.get_widget(filt_plot_id=plot_id)
42+
qtbot.mouseClick(pe.toolButton_modify, QtCore.Qt.LeftButton)
43+
44+
pv = mw.widget_ana_view.widget_plot
45+
46+
# This lead to:
47+
# Traceback (most recent call last):
48+
# File "/ShapeOut2/shapeout2/gui/analysis/ana_plot.py",
49+
# line 406, in on_axis_changed
50+
# self._set_contour_spacing_auto(axis_y=gen["axis y"])
51+
# File "/ShapeOut2/shapeout2/gui/analysis/ana_plot.py",
52+
# line 361, in _set_contour_spacing_auto
53+
# spacings_xy.append(np.min(spacings))
54+
# File "/numpy/core/fromnumeric.py", line 2618, in amin
55+
# initial=initial)
56+
# File "/numpy/core/fromnumeric.py", line 86, in _wrapreduction
57+
# return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
58+
# ValueError: zero-size array to reduction operation minimum which
59+
# has no identity
60+
pv.comboBox_axis_y.setCurrentIndex(pv.comboBox_axis_y.findData("emodulus"))
61+
62+
2163
def test_handle_empty_plots_issue_27(qtbot):
2264
"""Correctly handle empty plots
2365
@@ -27,7 +69,7 @@ def test_handle_empty_plots_issue_27(qtbot):
2769
qtbot.addWidget(mw)
2870

2971
# add a dataslot
30-
path = pathlib.Path(__file__).parent / "data" / "calibration_beads_47.rtdc"
72+
path = datapath / "calibration_beads_47.rtdc"
3173
mw.add_dataslot(paths=[path])
3274
# add another one
3375
mw.add_dataslot(paths=[path])
@@ -70,6 +112,19 @@ def test_handle_empty_plots_issue_27(qtbot):
70112
qtbot.mouseClick(pe, QtCore.Qt.LeftButton) # activate (raises #27)
71113

72114

115+
def test_handle_nan_valued_feature_color(qtbot):
116+
"""User wants to color scatter data points with feature containing nans"""
117+
spath = datapath / "version_2_1_2_plot_color_emodulus.so2"
118+
119+
mw = ShapeOut2()
120+
qtbot.addWidget(mw)
121+
122+
# lead to:
123+
# OverflowError: argument 4 overflowed: value must be in the range
124+
# -2147483648 to 2147483647
125+
mw.on_action_open(spath)
126+
127+
73128
def test_remove_plots_issue_36(qtbot):
74129
"""Correctly handle empty plots
75130
@@ -85,7 +140,7 @@ def test_remove_plots_issue_36(qtbot):
85140
qtbot.addWidget(mw)
86141

87142
# add a dataslots
88-
path = pathlib.Path(__file__).parent / "data" / "calibration_beads_47.rtdc"
143+
path = datapath / "calibration_beads_47.rtdc"
89144
mw.add_dataslot(paths=[path, path, path])
90145

91146
assert len(mw.pipeline.slot_ids) == 3, "we added those"

0 commit comments

Comments
 (0)