From e4b8c03456a59559a164c2ff1374c3eee5ec34c9 Mon Sep 17 00:00:00 2001 From: RaghavaAlajangi Date: Thu, 16 Oct 2025 11:15:55 +0200 Subject: [PATCH 01/10] Add zoom-in checkbox --- dcscope/gui/analysis/ana_plot.py | 1 + dcscope/gui/analysis/ana_plot.ui | 59 +++++++++++++++++--------------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/dcscope/gui/analysis/ana_plot.py b/dcscope/gui/analysis/ana_plot.py index 5535e8f..4294e1f 100644 --- a/dcscope/gui/analysis/ana_plot.py +++ b/dcscope/gui/analysis/ana_plot.py @@ -118,6 +118,7 @@ def read_pipeline_state(self): "contour": { "enabled": self.groupBox_contour.isChecked(), "legend": self.checkBox_legend.isChecked(), + "zoomin": self.checkBox_zoomin.isChecked(), "line widths": [self.doubleSpinBox_lw_1.value(), self.doubleSpinBox_lw_2.value(), ], diff --git a/dcscope/gui/analysis/ana_plot.ui b/dcscope/gui/analysis/ana_plot.ui index 5a2456e..2337f7f 100644 --- a/dcscope/gui/analysis/ana_plot.ui +++ b/dcscope/gui/analysis/ana_plot.ui @@ -7,7 +7,7 @@ 0 0 627 - 934 + 936 @@ -26,14 +26,14 @@ - QComboBox::AdjustToContents + QComboBox::SizeAdjustPolicy::AdjustToContents - Qt::Horizontal + Qt::Orientation::Horizontal @@ -52,8 +52,7 @@ Duplicate - - .. + @@ -66,8 +65,7 @@ Remove - - .. + @@ -76,7 +74,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -152,7 +150,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -228,7 +226,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -277,7 +275,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -311,7 +309,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -365,7 +363,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -431,7 +429,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -458,7 +456,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -483,7 +481,7 @@ - QLayout::SetDefaultConstraint + QLayout::SizeConstraint::SetDefaultConstraint @@ -519,7 +517,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -534,7 +532,7 @@ - QLayout::SetMinimumSize + QLayout::SizeConstraint::SetMinimumSize @@ -598,7 +596,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -692,7 +690,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -712,7 +710,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -914,7 +912,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -936,7 +934,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -958,13 +956,20 @@ + + + + Zoom-in + + + - Qt::Vertical + Qt::Orientation::Vertical @@ -979,7 +984,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -999,10 +1004,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed From 18c89d1dc04cea44b9507c1f94c7d1a86308ecaa Mon Sep 17 00:00:00 2001 From: RaghavaAlajangi Date: Thu, 16 Oct 2025 11:16:59 +0200 Subject: [PATCH 02/10] feat: add zoom-in functionality for contour plots --- dcscope/gui/pipeline_plot.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/dcscope/gui/pipeline_plot.py b/dcscope/gui/pipeline_plot.py index a242408..7f63ab7 100644 --- a/dcscope/gui/pipeline_plot.py +++ b/dcscope/gui/pipeline_plot.py @@ -361,6 +361,11 @@ def redraw(self, dslist, slot_states, plot_state, hash_flag=None): else: legend = None for rtdc_ds, ss in zip(dslist, slot_states): + if plot_state["contour"].get("zoomin", False): + zoomin_contours(dslist=dslist, + plot_item=self, + plot_state=plot_state + ) con = add_contour(plot_item=self, rtdc_ds=rtdc_ds, plot_state=plot_state, @@ -471,6 +476,34 @@ def add_label(text, anchor_parent, text_halign="center", text_valign="center", label.setPos(x + dx, y + dy) +def zoomin_contours(dslist, plot_item, plot_state, margin_per=5): + """Zoom-in contour data if enabled""" + x_min = float('inf') + x_max = float('-inf') + y_min = float('inf') + y_max = float('-inf') + # Get bounds from ALL contours at once + for rtdc_ds in dslist: + contours = compute_contours(plot_state=plot_state, rtdc_ds=rtdc_ds) + for contour in contours: + for cc in contour: + x_min = min(x_min, np.min(cc[:, 0])) + x_max = max(x_max, np.max(cc[:, 0])) + y_min = min(y_min, np.min(cc[:, 1])) + y_max = max(y_max, np.max(cc[:, 1])) + + # Add margin + x_margin = (x_max - x_min) * margin_per*0.01 + y_margin = (y_max - y_min) * margin_per*0.01 + + # Set view range with margins + plot_item.setRange( + xRange=(x_min - x_margin, x_max + x_margin), + yRange=(y_min - y_margin, y_max + y_margin), + padding=0 + ) + + def add_contour(plot_item, plot_state, rtdc_ds, slot_state, legend=None): contours = compute_contours(plot_state=plot_state, rtdc_ds=rtdc_ds) con = plot_state["contour"] From 2d2bb0c6c624135263efdd751c955532945dc85a Mon Sep 17 00:00:00 2001 From: RaghavaAlajangi Date: Thu, 16 Oct 2025 11:18:01 +0200 Subject: [PATCH 03/10] update changelog --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 89db1f6..af70539 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,5 @@ 2.23.3 + - feat: add zoom-in functionality for contour plots (#211) - fix: cache selected event per dataset in QuickView (#196) - enh: add new logo (scope view and block matrix) 2.22.2 From e8e0eb7cb1e9ccf5c5028149d2ad55650a90a398 Mon Sep 17 00:00:00 2001 From: RaghavaAlajangi Date: Thu, 16 Oct 2025 16:32:25 +0200 Subject: [PATCH 04/10] Add zoomin to DEFAULT_STATE and STATE_OPTIONS --- dcscope/pipeline/plot.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dcscope/pipeline/plot.py b/dcscope/pipeline/plot.py index 1a4eb5a..bd75727 100644 --- a/dcscope/pipeline/plot.py +++ b/dcscope/pipeline/plot.py @@ -44,6 +44,7 @@ "contour": { "enabled": True, "legend": False, # display plot legend + "zoomin": False, # enable zoom-in functionality "line widths": [3.0, 1.5], # contour line widths [pt] "line styles": ["solid", "dashed"], "percentiles": [95.0, 50.0], @@ -97,6 +98,7 @@ "contour": { "enabled": bool, "legend": bool, + "zoomin": bool, "line widths": (float,), "line styles": (["solid", "dashed", "dotted"],), "percentiles": (float,), From 187f2edc978088fa6791dfde6034837ea16d7d1b Mon Sep 17 00:00:00 2001 From: RaghavaAlajangi Date: Thu, 16 Oct 2025 16:32:35 +0200 Subject: [PATCH 05/10] update changelog --- CHANGELOG | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index af70539..d1b5985 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ -2.23.3 +2.24.0 - feat: add zoom-in functionality for contour plots (#211) +2.23.3 - fix: cache selected event per dataset in QuickView (#196) - enh: add new logo (scope view and block matrix) 2.22.2 From 9021bb6ca63e8f939d8e9e0f7e14c62aecb90239 Mon Sep 17 00:00:00 2001 From: RaghavaAlajangi Date: Thu, 16 Oct 2025 16:33:58 +0200 Subject: [PATCH 06/10] ref: optimize zoomin_contours logic --- dcscope/gui/pipeline_plot.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/dcscope/gui/pipeline_plot.py b/dcscope/gui/pipeline_plot.py index 7f63ab7..43b29e7 100644 --- a/dcscope/gui/pipeline_plot.py +++ b/dcscope/gui/pipeline_plot.py @@ -478,19 +478,21 @@ def add_label(text, anchor_parent, text_halign="center", text_valign="center", def zoomin_contours(dslist, plot_item, plot_state, margin_per=5): """Zoom-in contour data if enabled""" - x_min = float('inf') - x_max = float('-inf') - y_min = float('inf') - y_max = float('-inf') - # Get bounds from ALL contours at once - for rtdc_ds in dslist: - contours = compute_contours(plot_state=plot_state, rtdc_ds=rtdc_ds) - for contour in contours: - for cc in contour: - x_min = min(x_min, np.min(cc[:, 0])) - x_max = max(x_max, np.max(cc[:, 0])) - y_min = min(y_min, np.min(cc[:, 1])) - y_max = max(y_max, np.max(cc[:, 1])) + x_min, x_max, y_min, y_max = 0, 0, 0, 0 + # compute all contours + contours_list = [compute_contours(plot_state, ds) for ds in dslist] + + # flatten list of contours + flat_contours = [c for conts in contours_list for cont in conts + for c in cont if len(c) > 0] + if flat_contours: + # concatenate all points + all_points = np.concatenate(flat_contours, axis=0) + + x_min = np.min(all_points[:, 0]) + x_max = np.max(all_points[:, 0]) + y_min = np.min(all_points[:, 1]) + y_max = np.max(all_points[:, 1]) # Add margin x_margin = (x_max - x_min) * margin_per*0.01 From 27fd58b3f55b6449a823304e2cb1c96463bfd6a7 Mon Sep 17 00:00:00 2001 From: RaghavaAlajangi Date: Thu, 16 Oct 2025 17:19:01 +0200 Subject: [PATCH 07/10] fix: update version numbers in changelog --- CHANGELOG | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d1b5985..81788c6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,6 @@ -2.24.0 +2.23.0 - feat: add zoom-in functionality for contour plots (#211) -2.23.3 +2.22.3 - fix: cache selected event per dataset in QuickView (#196) - enh: add new logo (scope view and block matrix) 2.22.2 From cc023c525c66cb69c7646fe0a8f2050fc811db1b Mon Sep 17 00:00:00 2001 From: RaghavaAlajangi Date: Fri, 17 Oct 2025 10:57:12 +0200 Subject: [PATCH 08/10] ref: replcae np.concatenate with np.vstasck --- dcscope/gui/pipeline_plot.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dcscope/gui/pipeline_plot.py b/dcscope/gui/pipeline_plot.py index 43b29e7..cac4eb4 100644 --- a/dcscope/gui/pipeline_plot.py +++ b/dcscope/gui/pipeline_plot.py @@ -481,14 +481,11 @@ def zoomin_contours(dslist, plot_item, plot_state, margin_per=5): x_min, x_max, y_min, y_max = 0, 0, 0, 0 # compute all contours contours_list = [compute_contours(plot_state, ds) for ds in dslist] - # flatten list of contours - flat_contours = [c for conts in contours_list for cont in conts - for c in cont if len(c) > 0] - if flat_contours: - # concatenate all points - all_points = np.concatenate(flat_contours, axis=0) + all_points = np.vstack([np.vstack(c) for conts in contours_list + for c in conts]) + if all_points.size > 0: x_min = np.min(all_points[:, 0]) x_max = np.max(all_points[:, 0]) y_min = np.min(all_points[:, 1]) From 6e0a2d876a3b529307225d335c7742d27ff71e8f Mon Sep 17 00:00:00 2001 From: RaghavaAlajangi Date: Fri, 17 Oct 2025 11:02:52 +0200 Subject: [PATCH 09/10] enh: notify the user about zoomin option --- CHANGELOG | 1 - dcscope/gui/pipeline_plot.py | 9 +++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 81788c6..07409a9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,5 @@ 2.23.0 - feat: add zoom-in functionality for contour plots (#211) -2.22.3 - fix: cache selected event per dataset in QuickView (#196) - enh: add new logo (scope view and block matrix) 2.22.2 diff --git a/dcscope/gui/pipeline_plot.py b/dcscope/gui/pipeline_plot.py index cac4eb4..e19e735 100644 --- a/dcscope/gui/pipeline_plot.py +++ b/dcscope/gui/pipeline_plot.py @@ -539,6 +539,15 @@ def add_contour(plot_item, plot_state, rtdc_ds, slot_state, legend=None): text_valign="bottom", dy=-12, ) + if not con["zoomin"]: + # Notify the user about Zoom-In option. + add_label("Use 'Zoom-In' for better contour comparision.", + anchor_parent=plot_item.axes["top"]["item"], + font_size_diff=-1, + color="red", + text_halign="left", + text_valign="top", + ) return elements From 3faf974f4fd5f303d4990ce822c7d54babb8bef2 Mon Sep 17 00:00:00 2001 From: RaghavaAlajangi Date: Fri, 17 Oct 2025 12:21:28 +0200 Subject: [PATCH 10/10] ref: remove zoomin notification [skipci] --- dcscope/gui/pipeline_plot.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/dcscope/gui/pipeline_plot.py b/dcscope/gui/pipeline_plot.py index e19e735..cac4eb4 100644 --- a/dcscope/gui/pipeline_plot.py +++ b/dcscope/gui/pipeline_plot.py @@ -539,15 +539,6 @@ def add_contour(plot_item, plot_state, rtdc_ds, slot_state, legend=None): text_valign="bottom", dy=-12, ) - if not con["zoomin"]: - # Notify the user about Zoom-In option. - add_label("Use 'Zoom-In' for better contour comparision.", - anchor_parent=plot_item.axes["top"]["item"], - font_size_diff=-1, - color="red", - text_halign="left", - text_valign="top", - ) return elements