Summary
The Z-axis logarithmic scale tool (ZAxisLogTool) is permanently disabled in any plot whose image items are not direct ImageItem instances. This affects all downstream applications using XYImageItem, MaskedImageItem, MaskedXYImageItem, TrImageItem or RGBImageItem — most notably DataLab, where the image visualization panel uses MaskedXYImageItem.
Steps to reproduce
- Create a plot containing a
MaskedXYImageItem (or any other XYImageItem-derived item).
- Open the toolbar / menu and locate the Base-10 logarithmic Z axis action.
- Observe that the action is always greyed out, regardless of the item selection state.
In DataLab:
- Open the application and switch to the image panel.
- Add any image (e.g. via File > Open or Create > New image).
- The Base-10 logarithmic Z axis button on the toolbar remains disabled.
Expected behavior
The Z-axis log action should be enabled as soon as a supported image item is present (and selected, when several items coexist), and toggling it should switch the displayed image between linear and log scale.
Root cause
Two coupled issues in PlotPy:
-
In plotpy/tools/image.py, ZAxisLogTool.get_supported_items() filters items with:
isinstance(item, ImageItem)
and not item.is_empty()
and hasattr(item, "get_zaxis_log_state")
XYImageItem (and therefore MaskedXYImageItem) does not inherit from ImageItem (both inherit from RawImageItem), so the isinstance test fails immediately.
-
Even if the isinstance test were loosened, the hasattr check would still fail: the methods get_zaxis_log_state / set_zaxis_log_state (and the underlying _log_data / _lin_lut_range / _is_zaxis_log state) are defined only in ImageItem (plotpy/items/image/standard.py), not in any of the sibling classes.
As a result, get_supported_items() always returns [] and update_status() permanently disables the action.
Proposed fix
Refactor the Z-axis log API to live at the appropriate level in the class hierarchy, then loosen the tool filter:
-
plotpy/items/image/base.py — Move the log Z attributes (_log_data, _lin_lut_range, _is_zaxis_log) and methods (get_zaxis_log_state, set_zaxis_log_state) from ImageItem up to BaseImageItem. Add a plot is not None guard in set_zaxis_log_state for robustness.
-
plotpy/items/image/standard.py — Remove the now-duplicated log Z code from ImageItem. Add the if self.get_zaxis_log_state(): data = self._log_data branch in XYImageItem.draw_image() so that the _scale_xy call uses the precomputed log data when log mode is active. Clean up imports that are no longer needed locally (INTERP_AA, get_nan_range).
-
plotpy/items/image/transform.py — Mirror the same _log_data branch in TrImageItem.draw_image() before the _scale_tr call.
-
plotpy/tools/image.py — Replace isinstance(item, ImageItem) with isinstance(item, BaseImageItem) in ZAxisLogTool.get_supported_items(). The existing hasattr check keeps the filter safe for any custom subclass that does not implement the API.
Impact
- All built-in image item types (
ImageItem, XYImageItem, MaskedImageItem, MaskedXYImageItem, TrImageItem, RGBImageItem) now support Z-axis log scale out of the box.
- Downstream applications (e.g. DataLab) get the feature for free, with no changes required on their side.
- No public API change: only an additive move of methods to a parent class.
Summary
The Z-axis logarithmic scale tool (
ZAxisLogTool) is permanently disabled in any plot whose image items are not directImageIteminstances. This affects all downstream applications usingXYImageItem,MaskedImageItem,MaskedXYImageItem,TrImageItemorRGBImageItem— most notably DataLab, where the image visualization panel usesMaskedXYImageItem.Steps to reproduce
MaskedXYImageItem(or any otherXYImageItem-derived item).In DataLab:
Expected behavior
The Z-axis log action should be enabled as soon as a supported image item is present (and selected, when several items coexist), and toggling it should switch the displayed image between linear and log scale.
Root cause
Two coupled issues in PlotPy:
In
plotpy/tools/image.py,ZAxisLogTool.get_supported_items()filters items with:XYImageItem(and thereforeMaskedXYImageItem) does not inherit fromImageItem(both inherit fromRawImageItem), so theisinstancetest fails immediately.Even if the
isinstancetest were loosened, thehasattrcheck would still fail: the methodsget_zaxis_log_state/set_zaxis_log_state(and the underlying_log_data/_lin_lut_range/_is_zaxis_logstate) are defined only inImageItem(plotpy/items/image/standard.py), not in any of the sibling classes.As a result,
get_supported_items()always returns[]andupdate_status()permanently disables the action.Proposed fix
Refactor the Z-axis log API to live at the appropriate level in the class hierarchy, then loosen the tool filter:
plotpy/items/image/base.py— Move the log Z attributes (_log_data,_lin_lut_range,_is_zaxis_log) and methods (get_zaxis_log_state,set_zaxis_log_state) fromImageItemup toBaseImageItem. Add aplot is not Noneguard inset_zaxis_log_statefor robustness.plotpy/items/image/standard.py— Remove the now-duplicated log Z code fromImageItem. Add theif self.get_zaxis_log_state(): data = self._log_databranch inXYImageItem.draw_image()so that the_scale_xycall uses the precomputed log data when log mode is active. Clean up imports that are no longer needed locally (INTERP_AA,get_nan_range).plotpy/items/image/transform.py— Mirror the same_log_databranch inTrImageItem.draw_image()before the_scale_trcall.plotpy/tools/image.py— Replaceisinstance(item, ImageItem)withisinstance(item, BaseImageItem)inZAxisLogTool.get_supported_items(). The existinghasattrcheck keeps the filter safe for any custom subclass that does not implement the API.Impact
ImageItem,XYImageItem,MaskedImageItem,MaskedXYImageItem,TrImageItem,RGBImageItem) now support Z-axis log scale out of the box.