Skip to content

Fix resizing ViewBox if aspect locked + apply ViewBox limits immediately#2799

Merged
j9ac9k merged 2 commits intopyqtgraph:masterfrom
bbc131:pr_aspect_ratio
Oct 31, 2023
Merged

Fix resizing ViewBox if aspect locked + apply ViewBox limits immediately#2799
j9ac9k merged 2 commits intopyqtgraph:masterfrom
bbc131:pr_aspect_ratio

Conversation

@bbc131
Copy link
Copy Markdown
Contributor

@bbc131 bbc131 commented Aug 16, 2023

This commit fixes the following problems, whic occur if a ViewBox with locked aspect ratio is resized:

  1. The visible range changes suddenly at some points.
  2. The set limits are not taken into account.

Note, this PR fixes also Issue #2415. (Thanks @aksy2512 for #2540, I took some ideas from your PR.)

You can reproduce this with the mwe below:
Run the script and then slowly decrease the window width.
You'll observe, that the minimum visible y value will go beyond -5, which is set as yMin limit.
This is Issue 2.
If you continue to decrease the width, shortly after the y-axis labels 2 and -6 become visible, the y-range suddenly changes to around -4 ... 0, which is the above mentioned problem 1.

To improve traceability, I try to provide some info on why I changed what in the following:
This is, because my fix doesn't change one simple thing. Also I had some difficulties to understand the updateViewRange() function and still doesn't understand everything, especially the part within if aspect is not False ....

  • Adjusting viewRange to limits in updateViewRange() is necessary to fix the limits issue (2).
  • That adjusting targetRange, when changing viewRange is necessary shows me the mwe from ViewBox.setLimits() doesn't trigger update if view range not within new limits #2415:
    There, it all works fine if you increase the width of the LinearRegionItem, i.e. the right plot gets updated if necessary.
    But if you then decrease the width of the LinearRegionItem again, the right plots x-range also decreases! This is prevented by updating the targetRange here.
    • But, we must not reset all targetRange parts (i.e. simply call self._resetTarget()) since this causes the following problem:
      If you start decreasing the width of the LinearRegionItem again, you observe that the right plots x-range just slightly decreases before stopping!
      You might adjust the mwe and print the x-range on a change, i.e. add p2.getViewBox().sigXRangeChanged.connect(lambda vb, range: print(range)) to see this effect.
      This doesn't happen if we only adjust the targetRange parts whose corresponding viewRange parts we changed.
  • Regarding self._resetTarget(force=True) in resizeEvent(..), this fixes above described problem 1.
  • I want to keep the influence of my fix as small as possible, therefore I added the argument to self._resetTarget().
    It would be nice if we could get rid of this if self.state['aspectLocked'] is False completely.
    Maybe someone knows a case, where this is needed?!

Minimum-working-example:

import numpy as np
import pyqtgraph as pg

app = pg.mkQApp()
plot = pg.PlotWidget()
plot.show()

N = 10
data = np.eye(N) + np.flip(np.eye(N), axis=1)
for (n,m) in [(n,m) for n in (0,N-1) for m in (0,N-1)]:
    data[n,m] += 1.0
plot.addItem(pg.ImageItem(data, rect=[-N/2, -N/2, N, N]))
plot.showGrid(x=True, y=True)

plot.setLimits(xMin=-N/2,xMax=+N/2, yMin=-N/2, yMax=+N/2)

plot.setAspectLocked(lock=True, ratio=1.0)

plot.resize(400,200)
plot.setXRange(-5,+5)
plot.setYRange(-5,0)


if __name__ == '__main__':
    pg.exec()

This commit fixes the following problems, whic occur if a `ViewBox` with
locked aspect ratio is resized:

1. The visible range changes suddenly at some points.

2. The set limits are not taken into account.
@bbc131
Copy link
Copy Markdown
Contributor Author

bbc131 commented Aug 16, 2023

I see, that the behaviour on resize is changed.
I'll have a look at it this test in the next few days.

The previous commit broke the behavior for locked aspect ratio and
no limits on the view-range.

The previous and thereby desired behavior is the following:
Decreasing the size of a view keeps the view range constant, i.e.
does implicitly zoom-out.
If, afterwards, the size is increased again, the view range first
stays constant (i.e. implicit zoom-in) until the previous range and
zoom-level is reached again. Then, further increasing of the size
extends the view range (i.e. keeping zoom-level constant).
@j9ac9k
Copy link
Copy Markdown
Member

j9ac9k commented Oct 31, 2023

You've contributed enough to know that ViewBox.py is pretty complicated, and there is likely a lot of old/legacy codepaths there that are no longer relevant and just add to the confusion. One of my long-term goals was to greatly expand the test-code for ViewBox.py and then get to work on pruning out some of the more complex codepaths, in an attempt to simplify the class altogether.

That, is clearly out of scope for this PR tho.

Back to this PR, the fix you made looks good to me. Thanks for submitting it, and thank you @aksy2512 for the original PR that influenced this one.

@j9ac9k j9ac9k merged commit cdb177c into pyqtgraph:master Oct 31, 2023
@j9ac9k j9ac9k mentioned this pull request Mar 26, 2025
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.

2 participants