diff options
Diffstat (limited to 'src/silx/gui/plot/tools')
20 files changed, 106 insertions, 56 deletions
diff --git a/src/silx/gui/plot/tools/CurveLegendsWidget.py b/src/silx/gui/plot/tools/CurveLegendsWidget.py index 4a517dd..c9b0101 100644 --- a/src/silx/gui/plot/tools/CurveLegendsWidget.py +++ b/src/silx/gui/plot/tools/CurveLegendsWidget.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018-2020 European Synchrotron Radiation Facility @@ -25,8 +24,6 @@ """This module provides a widget to display :class:`PlotWidget` curve legends. """ -from __future__ import division - __authors__ = ["T. Vincent"] __license__ = "MIT" __date__ = "20/07/2018" diff --git a/src/silx/gui/plot/tools/LimitsToolBar.py b/src/silx/gui/plot/tools/LimitsToolBar.py index fc192a6..d7f4bf5 100644 --- a/src/silx/gui/plot/tools/LimitsToolBar.py +++ b/src/silx/gui/plot/tools/LimitsToolBar.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2016-2018 European Synchrotron Radiation Facility @@ -25,9 +24,6 @@ """A toolbar to display and edit limits of a PlotWidget """ - -from __future__ import division - __authors__ = ["V.A. Sole", "T. Vincent"] __license__ = "MIT" __date__ = "16/10/2017" diff --git a/src/silx/gui/plot/tools/PositionInfo.py b/src/silx/gui/plot/tools/PositionInfo.py index 8b95fbc..cb16b80 100644 --- a/src/silx/gui/plot/tools/PositionInfo.py +++ b/src/silx/gui/plot/tools/PositionInfo.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2016-2021 European Synchrotron Radiation Facility @@ -27,8 +26,6 @@ It can be configured to provide more information. """ -from __future__ import division - __authors__ = ["V.A. Sole", "T. Vincent"] __license__ = "MIT" __date__ = "16/10/2017" @@ -239,7 +236,7 @@ class PositionInfo(qt.QWidget): ratio = qt.QGuiApplication.primaryScreen().devicePixelRatio() # Baseline squared distance threshold - distInPixels = (self.SNAP_THRESHOLD_DIST * ratio)**2 + sqDistInPixels = (self.SNAP_THRESHOLD_DIST * ratio)**2 for item in selectedItems: if (snappingMode & self.SNAPPING_SYMBOLS_ONLY and ( @@ -263,33 +260,36 @@ class PositionInfo(qt.QWidget): break else: # Curve, Scatter - xArray = item.getXData(copy=False) - yArray = item.getYData(copy=False) - closestIndex = numpy.argmin( - pow(xArray - x, 2) + pow(yArray - y, 2)) - - xClosest = xArray[closestIndex] - yClosest = yArray[closestIndex] + result = item.pick(xPixel, yPixel) + if result is None: + continue + indices = result.getIndices(copy=False) + if indices is None: + continue if isinstance(item, items.YAxisMixIn): axis = item.getYAxis() else: axis = 'left' - closestInPixels = plot.dataToPixel( - xClosest, yClosest, axis=axis) - if closestInPixels is not None: - curveDistInPixels = ( - (closestInPixels[0] - xPixel)**2 + - (closestInPixels[1] - yPixel)**2) - - if curveDistInPixels <= distInPixels: - # Update label style sheet - styleSheet = "color: rgb(0, 0, 0);" + xArray = item.getXData(copy=False)[indices] + yArray = item.getYData(copy=False)[indices] + pixelPositions = plot.dataToPixel(xArray, yArray, axis=axis) + if pixelPositions is None: + continue + sqDistances = (pixelPositions[0] - xPixel)**2 + (pixelPositions[1] - yPixel)**2 + if not numpy.any(numpy.isfinite(sqDistances)): + continue + closestIndex = numpy.nanargmin(sqDistances) + closestSqDistInPixels = sqDistances[closestIndex] + + if closestSqDistInPixels <= sqDistInPixels: + # Update label style sheet + styleSheet = "color: rgb(0, 0, 0);" - # if close enough, snap to data point coord - xData, yData = xClosest, yClosest - distInPixels = curveDistInPixels + # if close enough, snap to data point coord + xData, yData = xArray[closestIndex], yArray[closestIndex] + sqDistInPixels = closestSqDistInPixels for label, name, func in self._fields: label.setStyleSheet(styleSheet) diff --git a/src/silx/gui/plot/tools/RadarView.py b/src/silx/gui/plot/tools/RadarView.py index 7076835..886f37e 100644 --- a/src/silx/gui/plot/tools/RadarView.py +++ b/src/silx/gui/plot/tools/RadarView.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2015-2018 European Synchrotron Radiation Facility diff --git a/src/silx/gui/plot/tools/__init__.py b/src/silx/gui/plot/tools/__init__.py index 09f468c..5b6b74c 100644 --- a/src/silx/gui/plot/tools/__init__.py +++ b/src/silx/gui/plot/tools/__init__.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018 European Synchrotron Radiation Facility diff --git a/src/silx/gui/plot/tools/profile/ScatterProfileToolBar.py b/src/silx/gui/plot/tools/profile/ScatterProfileToolBar.py index 44187ef..09f90b7 100644 --- a/src/silx/gui/plot/tools/profile/ScatterProfileToolBar.py +++ b/src/silx/gui/plot/tools/profile/ScatterProfileToolBar.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018-2019 European Synchrotron Radiation Facility diff --git a/src/silx/gui/plot/tools/profile/__init__.py b/src/silx/gui/plot/tools/profile/__init__.py index d91191e..a72b5d2 100644 --- a/src/silx/gui/plot/tools/profile/__init__.py +++ b/src/silx/gui/plot/tools/profile/__init__.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018 European Synchrotron Radiation Facility diff --git a/src/silx/gui/plot/tools/profile/core.py b/src/silx/gui/plot/tools/profile/core.py index 200f5cf..5d4a674 100644 --- a/src/silx/gui/plot/tools/profile/core.py +++ b/src/silx/gui/plot/tools/profile/core.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018-2020 European Synchrotron Radiation Facility diff --git a/src/silx/gui/plot/tools/profile/editors.py b/src/silx/gui/plot/tools/profile/editors.py index 80e0452..1d6f198 100644 --- a/src/silx/gui/plot/tools/profile/editors.py +++ b/src/silx/gui/plot/tools/profile/editors.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018-2020 European Synchrotron Radiation Facility @@ -252,7 +251,10 @@ class ProfileRoiEditorAction(qt.QWidgetAction): return layout = widget.layout() if previousEditor is not None: - previousEditor.sigDataCommited.disconnect(self._editorDataCommited) + try: + previousEditor.sigDataCommited.disconnect(self._editorDataCommited) + except (RuntimeError, TypeError): + pass layout.removeWidget(previousEditor) previousEditor.deleteLater() if editor is not None: diff --git a/src/silx/gui/plot/tools/profile/manager.py b/src/silx/gui/plot/tools/profile/manager.py index 4a22bc0..58c1c86 100644 --- a/src/silx/gui/plot/tools/profile/manager.py +++ b/src/silx/gui/plot/tools/profile/manager.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018-2021 European Synchrotron Radiation Facility @@ -180,6 +179,8 @@ class ProfileWindow(qt.QMainWindow): plot.setDataMargins(yMinMargin=0.1, yMaxMargin=0.1) plot.setGraphYLabel('Profile') plot.setGraphXLabel('') + positionInfo = plot.getPositionInfoWidget() + positionInfo.setSnappingMode(positionInfo.SNAPPING_CURVE) return plot def createPlot2D(self, parent, backend): diff --git a/src/silx/gui/plot/tools/profile/rois.py b/src/silx/gui/plot/tools/profile/rois.py index 9eef622..042aff1 100644 --- a/src/silx/gui/plot/tools/profile/rois.py +++ b/src/silx/gui/plot/tools/profile/rois.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018-2021 European Synchrotron Radiation Facility @@ -945,13 +944,19 @@ class _DefaultScatterProfileSliceRoiMixIn(core.ProfileRoiMixIn): if major_axis: # slice in the middle of the scatter - start = max_grid_second // 2 * max_grid_first - vslice = axis[start:start + max_grid_second] + actual_size_grid_second = len(axis) // max_grid_first + start = actual_size_grid_second // 2 * max_grid_first + vslice = axis[start:start + max_grid_first] + if len(vslice) == 0: + return None index = argnearest(vslice, position) slicing = slice(index, None, max_grid_first) else: # slice in the middle of the scatter - vslice = axis[max_grid_second // 2::max_grid_second] + actual_size_grid_second = len(axis) // max_grid_first + vslice = axis[actual_size_grid_second // 2::max_grid_second] + if len(vslice) == 0: + return None index = argnearest(vslice, position) start = index * max_grid_second slicing = slice(start, start + max_grid_second) @@ -1086,11 +1091,14 @@ class _DefaultImageStackProfileRoiMixIn(_DefaultImageProfileRoiMixIn): coords, profile, profileName, xLabel = createProfile2(currentData) + profileManager = self.getProfileManager() + plot = profileManager.getPlotWidget() + data = core.ImageProfileData( coords=coords, profile=profile, - title=profileName, - xLabel=xLabel, + title=_relabelAxes(plot, profileName), + xLabel=_relabelAxes(plot, xLabel), yLabel="Profile", colormap=colormap, ) diff --git a/src/silx/gui/plot/tools/profile/toolbar.py b/src/silx/gui/plot/tools/profile/toolbar.py index 4a9a195..12a734a 100644 --- a/src/silx/gui/plot/tools/profile/toolbar.py +++ b/src/silx/gui/plot/tools/profile/toolbar.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018-2019 European Synchrotron Radiation Facility diff --git a/src/silx/gui/plot/tools/roi.py b/src/silx/gui/plot/tools/roi.py index e4be6a7..1da692c 100644 --- a/src/silx/gui/plot/tools/roi.py +++ b/src/silx/gui/plot/tools/roi.py @@ -1,7 +1,6 @@ -# coding: utf-8 # /*########################################################################## # -# Copyright (c) 2018-2021 European Synchrotron Radiation Facility +# Copyright (c) 2018-2022 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -381,6 +380,7 @@ class RegionOfInterestManager(qt.QObject): roi_items.VerticalLineROI, roi_items.ArcROI, roi_items.HorizontalRangeROI, + roi_items.BandROI, ) def __init__(self, parent): diff --git a/src/silx/gui/plot/tools/test/__init__.py b/src/silx/gui/plot/tools/test/__init__.py index aa4a601..2e682d7 100644 --- a/src/silx/gui/plot/tools/test/__init__.py +++ b/src/silx/gui/plot/tools/test/__init__.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018 European Synchrotron Radiation Facility diff --git a/src/silx/gui/plot/tools/test/testCurveLegendsWidget.py b/src/silx/gui/plot/tools/test/testCurveLegendsWidget.py index 37af10e..657d328 100644 --- a/src/silx/gui/plot/tools/test/testCurveLegendsWidget.py +++ b/src/silx/gui/plot/tools/test/testCurveLegendsWidget.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018 European Synchrotron Radiation Facility diff --git a/src/silx/gui/plot/tools/test/testProfile.py b/src/silx/gui/plot/tools/test/testProfile.py index 829f49e..ad40e67 100644 --- a/src/silx/gui/plot/tools/test/testProfile.py +++ b/src/silx/gui/plot/tools/test/testProfile.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018-2021 European Synchrotron Radiation Facility diff --git a/src/silx/gui/plot/tools/test/testROI.py b/src/silx/gui/plot/tools/test/testROI.py index 21697d1..6ce1553 100644 --- a/src/silx/gui/plot/tools/test/testROI.py +++ b/src/silx/gui/plot/tools/test/testROI.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018-2020 European Synchrotron Radiation Facility @@ -268,6 +267,12 @@ class TestRoiItems(TestCaseQt): self.assertAlmostEqual(item.getMax(), vmax) self.assertAlmostEqual(item.getCenter(), 2) + def testBand_getToSetGeometry(self): + """Test that we can use getGeometry as input to setGeometry""" + item = roi_items.BandROI() + item.setFirstShapePoints(numpy.array([[5, 10], [50, 100]])) + item.setGeometry(*item.getGeometry()) + class TestRegionOfInterestManager(TestCaseQt, ParametricTestCase): """Tests for RegionOfInterestManager class""" @@ -577,7 +582,7 @@ class TestRegionOfInterestManager(TestCaseQt, ParametricTestCase): manager.addRoi(item) self.qapp.processEvents() - # Drag the center + # Drag the center widget = self.plot.getWidgetHandle() mx, my = self.plot.dataToPixel(*center) self.mouseMove(widget, pos=(mx, my)) @@ -680,3 +685,56 @@ class TestRegionOfInterestManager(TestCaseQt, ParametricTestCase): manager.clear() self.qapp.processEvents() + + def testBandRoiSwitchMode(self): + """Make sure we can switch mode by clicking on the ROI""" + xlimit = self.plot.getXAxis().getLimits() + ylimit = self.plot.getYAxis().getLimits() + xcenter = 0.5 * (xlimit[0] + xlimit[1]) + ycenter = 0.5 * (ylimit[0] + ylimit[1]) + + # Create the line + manager = roi.RegionOfInterestManager(self.plot) + item = roi_items.BandROI() + item.setGeometry( + (xlimit[0], ycenter), + (xlimit[1], ycenter), + 20, + ) + item.setEditable(True) + item.setSelectable(True) + manager.addRoi(item) + self.qapp.processEvents() + + # Initial state + assert item.getInteractionMode() is roi_items.BandROI.BoundedMode + self.qWait(500) + + # Click on the center + widget = self.plot.getWidgetHandle() + mx, my = self.plot.dataToPixel(xcenter, ycenter) + + # Select the ROI + self.mouseMove(widget, pos=(mx, my)) + self.mouseClick(widget, qt.Qt.LeftButton, pos=(mx, my)) + self.qWait(500) + assert item.getInteractionMode() is roi_items.BandROI.BoundedMode + + # Change the mode + self.mouseMove(widget, pos=(mx, my)) + self.mouseClick(widget, qt.Qt.LeftButton, pos=(mx, my)) + self.qWait(500) + assert item.getInteractionMode() is roi_items.BandROI.UnboundedMode + + # Set available modes that exclude the current one + item.setAvailableInteractionModes([roi_items.BandROI.BoundedMode]) + assert item.getInteractionMode() is roi_items.BandROI.BoundedMode + + # Clicking does not change the mode since there is only one + self.mouseMove(widget, pos=(mx, my)) + self.mouseClick(widget, qt.Qt.LeftButton, pos=(mx, my)) + self.qWait(500) + assert item.getInteractionMode() is roi_items.BandROI.BoundedMode + + manager.clear() + self.qapp.processEvents() diff --git a/src/silx/gui/plot/tools/test/testScatterProfileToolBar.py b/src/silx/gui/plot/tools/test/testScatterProfileToolBar.py index 582a276..9b9caa1 100644 --- a/src/silx/gui/plot/tools/test/testScatterProfileToolBar.py +++ b/src/silx/gui/plot/tools/test/testScatterProfileToolBar.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018 European Synchrotron Radiation Facility diff --git a/src/silx/gui/plot/tools/test/testTools.py b/src/silx/gui/plot/tools/test/testTools.py index 846f641..507b922 100644 --- a/src/silx/gui/plot/tools/test/testTools.py +++ b/src/silx/gui/plot/tools/test/testTools.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2016-2021 European Synchrotron Radiation Facility diff --git a/src/silx/gui/plot/tools/toolbars.py b/src/silx/gui/plot/tools/toolbars.py index 3df7d06..bb89942 100644 --- a/src/silx/gui/plot/tools/toolbars.py +++ b/src/silx/gui/plot/tools/toolbars.py @@ -1,4 +1,3 @@ -# coding: utf-8 # /*########################################################################## # # Copyright (c) 2018-2020 European Synchrotron Radiation Facility |