Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImageItem: implement persistent default autolevels #2883

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

pijyoi
Copy link
Contributor

@pijyoi pijyoi commented Nov 18, 2023

Allow user to set whether to perform auto levels by default instead of having to specify it on each data change.
The original behavior is that if unspecified, autoLevels==True. i.e. the user needs to specify autoLevels=False explicitly on each data change.

The example from #2830 (comment) becomes

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore
import numpy as np

rng = np.random.default_rng(0)

pg.mkQApp()
glw = pg.GraphicsLayoutWidget()
glw.show()
plot = pg.PlotItem()
img = pg.ImageItem(axisOrder='row-major', autoLevels=False)
assert img.getLevels() is None
plot.addItem(img)
hlut = pg.HistogramLUTItem()
hlut.setImageItem(img)
# HistogramLUTItem immediately sets levels [0, 1] to the ImageItem 
assert img.getLevels() is not None
hlut.setHistogramRange(0, 10)
glw.addItem(plot, row=0, col=0)
glw.addItem(hlut, row=0, col=1)

# set the levels manually 
img.setLevels([0, 4])

def update():
    noise = rng.rayleigh(size=(100,100))
    XY = np.sinc(np.linspace(-10, 10, 100))
    s = rng.random(1)
    data = s * 10 * np.abs(XY[:, np.newaxis] * XY)**2 + noise
    img.setImage(data)

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(100)

pg.exec()

Oh, a plug for #2779: if you are running off master, right-clicking on the colorbar now exposes all the colormaps bundled with pyqtgraph.

@pijyoi pijyoi mentioned this pull request Nov 18, 2023
@pijyoi
Copy link
Contributor Author

pijyoi commented Nov 18, 2023

If I were to implement enableAutoLevels as a keyword argument for ImageItem to follow PColorMeshItem's API to allow setting during object instantiation, the API becomes weird for ImageItem.

ImageItem has a setOpts method that is called in both __init__ and setImage. If enableAutoLevels were implemented in setOpts, then it would become possible for the user to do the following:
setImage(..., autoLevels=<something>, enableAutoLevels=<something>)

@pijyoi
Copy link
Contributor Author

pijyoi commented Nov 18, 2023

Perhaps enableAutoLevels should be named as autoLevels. This is consistent with the rest of the keyword arguments.
Then in setImage, if autoLevels is present as a keyword argument, it will not get passed on to setOpts.
This is also intuitive in that setImage(autoLevels=<something>) is only supposed to override the persistent value temporarily.

@pijyoi pijyoi force-pushed the imageitem-default-autolevels branch 2 times, most recently from 73c1b56 to 67b114f Compare November 19, 2023 04:45
@pijyoi
Copy link
Contributor Author

pijyoi commented Nov 19, 2023

I have reworked things to be more consistent with the API of ImageItem itself.

If the user wants to instantiate ImageItem with autoLevels=False,

  1. if the data type is float, they have to call setLevels manually
  2. if the data type is integer, they can leave out calling setLevels, in which case levels is taken to be the min, max of the underlying data type.
    The above behavior is inherent to the implementation of ImageItem, and is not modified by this PR to retain compatibility.

@pijyoi pijyoi force-pushed the imageitem-default-autolevels branch from 67b114f to fe0cea6 Compare November 19, 2023 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant