Skip to content

Commit a37af8a

Browse files
committed
Colormap tools: update only image item colormap (not the whole parameters set)
Fix #24
1 parent 6501285 commit a37af8a

File tree

3 files changed

+31
-21
lines changed

3 files changed

+31
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
🛠️ Bug fixes:
66

7+
* [Issue #24](https://github.com/PlotPyStack/PlotPy/issues/24) - Colormap: side effect on image axes when changing the colormap
78
* [Issue #23](https://github.com/PlotPyStack/PlotPy/issues/23) - Windows: Image `_scaler` engine performance regression
89
* PySide6 compatibility issues:
910
* Fixed deprecated call to `QMouseEvent` in `tests/unit/utils.py`

plotpy/tests/features/test_image_data_update.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import pytest
2424
from guidata.qthelpers import exec_dialog, qt_app_context
2525
from qtpy import QtCore as QC
26+
from qtpy import QtGui as QG
2627
from qtpy import QtWidgets as QW
2728

2829
from plotpy.builder import make
@@ -31,39 +32,41 @@
3132
from plotpy.tools import LockLUTRangeTool
3233

3334

34-
def get_data() -> np.ndarray:
35+
def get_data(variable_size: bool) -> np.ndarray:
3536
"""Compute 2D Gaussian data and add a narrower Gaussian on top with a random
3637
position and amplitude."""
38+
size = np.random.randint(50, 200) if variable_size else 100
3739
dtype = np.uint16
3840
amp = np.iinfo(dtype).max * 0.3
39-
data = ptd.gen_2d_gaussian(100, dtype, sigma=10.0, x0=0.0, y0=0.0, amp=amp)
41+
data = ptd.gen_2d_gaussian(size, dtype, sigma=10.0, x0=0.0, y0=0.0, amp=amp)
4042
# Choose a random position: x0, y0 have to be in the range [-10.0, 10.0]
4143
x0 = np.random.uniform(-10.0, 10.0)
4244
y0 = np.random.uniform(-10.0, 10.0)
4345
# Choose a random amplitude: a has to be in the range [0.1, 0.5]
4446
a = np.random.uniform(0.1, 0.7) * np.iinfo(dtype).max
4547
# Add the narrower Gaussian on top
46-
data += ptd.gen_2d_gaussian(100, dtype, sigma=4.0, x0=x0, y0=y0, amp=a)
48+
data += ptd.gen_2d_gaussian(size, dtype, sigma=4.0, x0=x0, y0=y0, amp=a)
4749
return data
4850

4951

5052
class ImageUpdateDialog(PlotDialog):
5153
"""Dialog box for image update"""
5254

53-
def __init__(self, title):
55+
def __init__(self, title: str, variable_size: bool = False) -> None:
56+
self.variable_size = variable_size
5457
options = PlotOptions(title="-", show_contrast=True, type="image")
5558
super().__init__(title=title, toolbar=True, edit=False, options=options)
5659
self.resize(600, 600)
5760
self.timer = QC.QTimer()
58-
self.item = make.image(get_data(), interpolation="nearest")
61+
self.item = make.image(get_data(self.variable_size), interpolation="nearest")
5962
self.item.set_lut_range((15000, 28000))
6063
plot = self.get_plot()
6164
plot.add_item(self.item)
6265
plot.set_active_item(self.item, select=False)
6366
self.counter = 0
6467
self.keep_lut_cb: QW.QCheckBox | None = None
6568

66-
def populate_plot_layout(self):
69+
def populate_plot_layout(self) -> None:
6770
"""Populate the plot layout"""
6871
start_btn = QW.QPushButton("Start image update")
6972
start_btn.clicked.connect(self.start_image_update)
@@ -74,9 +77,17 @@ def populate_plot_layout(self):
7477
self.keep_lut_cb = QW.QCheckBox()
7578
self.keep_lut_cb.setChecked(False)
7679
self.add_widget(self.keep_lut_cb, 0, 2)
80+
variable_size_cb = QW.QCheckBox("Variable size")
81+
variable_size_cb.setChecked(self.variable_size)
82+
variable_size_cb.stateChanged.connect(self.toggle_variable_size)
83+
self.add_widget(variable_size_cb, 0, 3)
7784
self.add_widget(self.plot_widget, 1, 0, 1, 0)
7885

79-
def register_tools(self):
86+
def toggle_variable_size(self, state: int) -> None:
87+
"""Toggle the variable size of the image"""
88+
self.variable_size = state == QC.Qt.Checked
89+
90+
def register_tools(self) -> None:
8091
"""Reimplement to connect the Keep LUT range checkbox to the item"""
8192
mgr = self.get_manager()
8293
keep_lut_tool = mgr.add_tool(LockLUTRangeTool)
@@ -87,18 +98,18 @@ def register_tools(self):
8798
self.keep_lut_cb.setToolTip(keep_lut_tool.action.toolTip())
8899
self.keep_lut_cb.stateChanged.connect(keep_lut_tool.activate)
89100

90-
def start_image_update(self):
101+
def start_image_update(self) -> None:
91102
"""Start updating the image"""
92103
self.timer.timeout.connect(self.update_image)
93104
self.timer.start(500)
94105

95-
def stop_image_update(self):
106+
def stop_image_update(self) -> None:
96107
"""Stop updating the image"""
97108
self.timer.stop()
98109

99-
def update_image(self):
110+
def update_image(self) -> None:
100111
"""Update the image"""
101-
data = get_data()
112+
data = get_data(self.variable_size)
102113
self.counter += 1
103114
plot = self.get_plot()
104115

@@ -111,7 +122,7 @@ def update_image(self):
111122
plot.set_title(f"Image update {self.counter:03d}")
112123
plot.replot()
113124

114-
def closeEvent(self, event):
125+
def closeEvent(self, event: QG.QCloseEvent) -> None:
115126
"""Reimplement closeEvent to stop the timer before closing the dialog"""
116127
self.timer.stop()
117128
super().closeEvent(event)

plotpy/tools/image.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -642,18 +642,17 @@ def activate_cmap(self, cmap: str | EditableColormap) -> None:
642642
self.update_plot(self._active_colormap.name)
643643
self.update_status(plot)
644644

645-
def update_plot(self, cmap: str) -> None:
645+
def update_plot(self, cmap_name: str) -> None:
646646
"""Update the plot with the given colormap.
647647
648648
Args:
649-
cmap: Colormap name
649+
cmap_name: Colormap name
650650
"""
651651
plot: BasePlot = self.get_active_plot()
652652
items = get_selected_images(plot, IColormapImageItemType)
653653
for item in items:
654-
param: BaseImageParam = item.param
655-
param.colormap = cmap
656-
param.update_item(item)
654+
cmap = item.get_color_map()
655+
item.set_color_map(cmap_name, cmap.invert)
657656
plot.SIG_ITEM_PARAMETERS_CHANGED.emit(item)
658657
plot.invalidate()
659658

@@ -705,10 +704,9 @@ def activate_command(self, plot: BasePlot, checked: bool) -> None:
705704
if self._active_colormap is not None and plot is not None:
706705
items = get_selected_images(plot, IColormapImageItemType)
707706
for item in items:
708-
param: BaseImageParam = item.param
709-
param.invert_colormap = checked
710-
param.update_item(item)
711-
plot.SIG_ITEM_PARAMETERS_CHANGED.emit(item)
707+
cmap = item.get_color_map()
708+
item.set_color_map(cmap.name, invert=checked)
709+
plot.SIG_ITEM_PARAMETERS_CHANGED.emit(item)
712710
plot.invalidate()
713711
self.update_status(plot)
714712

0 commit comments

Comments
 (0)