Is there any way to restrict the range that a user can interactively pan a plot in matplotlib?
For example, I'd like to limit the user's panning range to the positive quadrant of the plot, so x > 0 and y > 0, effectively creating floors at x = 0 and y = 0.
Asked
Active
Viewed 592 times
0

ImportanceOfBeingErnest
- 321,279
- 53
- 665
- 712

Daniel Kocevski
- 371
- 1
- 4
- 13
1 Answers
0
There is not built-in way to restrict zooming or panning other than restricting it to either the x or y direction. So you need to implement that yourself.
Connecting to the 'xlim_changed'
and 'ylim_changed'
events, you may check if the limits are valid or not, and potentially reset them to the valid range.
import matplotlib.pyplot as plt
import numpy as np
fig,ax=plt.subplots()
x = np.sin(np.linspace(0,10, 266))+1
ax.plot(x)
class Restrictor():
def __init__(self, ax, x=lambda x: True,y=lambda x: True):
self.res = [x,y]
self.ax =ax
self.limits = self.get_lim()
self.ax.callbacks.connect('xlim_changed', lambda evt: self.lims_change(axis=0))
self.ax.callbacks.connect('ylim_changed', lambda evt: self.lims_change(axis=1))
def get_lim(self):
return [self.ax.get_xlim(), self.ax.get_ylim()]
def set_lim(self, axis, lim):
if axis==0:
self.ax.set_xlim(lim)
else:
self.ax.set_ylim(lim)
self.limits[axis] = self.get_lim()[axis]
def lims_change(self, event=None, axis=0):
curlim = np.array(self.get_lim()[axis])
if self.limits[axis] != self.get_lim()[axis]:
# avoid recursion
if not np.all(self.res[axis](curlim)):
# if limits are invalid, reset them to previous state
self.set_lim(axis, self.limits[axis])
else:
# if limits are valid, update previous stored limits
self.limits[axis] = self.get_lim()[axis]
res = Restrictor(ax, x=lambda x: x>=0,y=lambda x: x>=0)
plt.show()
The user experience of such limitations are not great, since a certain action (like moving the mouse) is not answered with the expected behaviour (plot does not move); but one has to judge for oneself if this would still make sense.

ImportanceOfBeingErnest
- 321,279
- 53
- 665
- 712