silx icon indicating copy to clipboard operation
silx copied to clipboard

silx.gui.plot: Added support for non-uniform images in matplotlib backend

Open malte-storm opened this issue 1 year ago • 2 comments

Added support for matplotlib NonUniformImages in the silx.gui.plot module.

Motivation for this change: When changing for example 2d-integration results from Q/2theta to d-spacing for analysis, the Q/2theta axis becomes non-linear and could not be displayed property for 2d-data.

A new addNonUniformImage(x, y, data) method which follows the syntax of matplotlib's NonUniformImage.set_data(x, y, data) syntax has been added to the PlotWidget with minor refactoring of the addImage to allow reusing code for both addImage and addNonUniformImage.

The change has also been integrated in the Backends (and the OpenGL backend gives a warning and displays plot as "normal" images) and in the ImageData class.

Possible open issue: The addNonUniformImage is not implemented for RGB(A) data, I could not easily find out if this would really be used anywhere.

malte-storm avatar Jul 31 '24 05:07 malte-storm

Thanks for the Pull Request! It would be great to have support for non-uniform images.

However, from a first look at it, it sounds that it will more complicated to fully support non uniform image: We need to make sure all provided data (x and y) can be retrieved from the item, and that all features (displaying the value below the mouse cursor, profile, mask...) fully supports it.

To do so, instead of adding this support to the ImageData, a new plot NonUniformImageData item would be needed (something a bit like https://github.com/silx-kit/silx/blob/main/src/silx/gui/plot/items/image_aggregated.py). Also, for new items, we tend to not add extra methods to PlotWidget.add*, but rather use PlotWidget.addItem.

Finally, here is a code snippet that uses numpy.meshgrid and a Scatter item to provide a similar feature:

import numpy as np
from silx.gui import qt
from silx.gui.plot import PlotWidget
from silx.gui.plot.items import Scatter

x = [1, 2, 4]
y = [0, 2, 3]
values = np.arange(9).reshape(3, 3)

app = qt.QApplication([])

scatter = Scatter()

scatter_x, scatter_y = np.meshgrid(x, y)
scatter.setData(scatter_x.ravel(), scatter_y.ravel(), values.ravel())
scatter.setVisualization(scatter.Visualization.IRREGULAR_GRID)

plot = PlotWidget()
plot.addItem(scatter)
plot.resetZoom()
plot.show()

app.exec()
image

The Scatter code uses the backend's addTriangles method to render the image:

https://github.com/silx-kit/silx/blob/a7da2634a2a26e1b77ea3e4bdf080027da2a7c0a/src/silx/gui/plot/backends/BackendBase.py#L169-L180

That could be also used in a NonUniformImageData item.

t20100 avatar Jul 31 '24 19:07 t20100

Thanks for the feedback and the suggestion how to display non-uniform images using the scatter method. I will take an in-depth look after the summer break.

malte-storm avatar Aug 01 '24 05:08 malte-storm