Skip to content

Z-axis log tool always disabled for non-ImageItem image types #59

@PierreRaybaut

Description

@PierreRaybaut

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

  1. Create a plot containing a MaskedXYImageItem (or any other XYImageItem-derived item).
  2. Open the toolbar / menu and locate the Base-10 logarithmic Z axis action.
  3. Observe that the action is always greyed out, regardless of the item selection state.

In DataLab:

  1. Open the application and switch to the image panel.
  2. Add any image (e.g. via File > Open or Create > New image).
  3. 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:

  1. 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.

  2. 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:

  1. 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.

  2. 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).

  3. plotpy/items/image/transform.py — Mirror the same _log_data branch in TrImageItem.draw_image() before the _scale_tr call.

  4. 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.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions