Constraining Movement
Contents
Constraining Movement#
You can constrain the line to move only horizontally, or only vertically similar to matplotlib’s axhline
and axhline
.
There are two ways to accomplish this:
1. lock_x
and lock_y
#
The DraggableLine
has settable lock_x
and lock_y
properties which can be changed at any point to prevent or allow movement in x
or y
respectively.
# choose backend if in a jupyter notebook
%matplotlib widget
from __future__ import annotations
import matplotlib.pyplot as plt
from mpl_draggable_line import DraggableLine
fig, ax = plt.subplots()
init_x = [0.25, 0.5]
init_y = [0.25, 0.5]
dl = DraggableLine(ax, init_x, init_y)
dl.lock_orientation = True
# Freeze in x
# dl.lock_x = True
# Freeze in y
# dl.lock_y = True
plt.show()
2. lock_orientation
#
Even with locking one of the dimensions you can still have unexpected behavior if you grab one the handles on the end of the lines. This will result in one handle moving, but constrained to either x or y. If you would instead like to move the entire line as a stiff object then you set lock_orientation
to True
dl.lock_orientation = True
You can always release the locks:
dl.lock_x = False
dl.lock_orientation = False
3. Using DraggableHLine
and DraggableVLine
#
You can also use either the DraggableHLine
or DraggableVLine
subclasses to accomplish the same. These subclasses three advantages over using a raw DraggableLine
.
They use a different matplotlib transform so they will go to the edges of the plot - like axvline and axhline.
They adjust the callback to only be passed a single number rather than
(x[0], x[1], y[0], y[1])
.You only need to pass a single number on initialization rather than 4 numbers.
from mpl_draggable_line import DraggableVLine, DraggableHLine
fig, axs = plt.subplots(1, 2)
dl_h = DraggableHLine(axs[0], .5)
dl_v = DraggableVLine(axs[1], .5)
def h_callback(y: float):
axs[0].set_title(f"y pos: {y:0.2f}")
dl_h.on_line_changed(h_callback)
def v_callback(x: float):
axs[1].set_title(f"x pos: {x:0.2f}")
dl_v.on_line_changed(v_callback)
plt.show()