Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -1730,6 +1730,7 @@ class FigureCanvasBase:
events = [
'resize_event',
'draw_event',
'pre_draw_event',
'key_press_event',
'key_release_event',
'button_press_event',
Expand Down Expand Up @@ -2333,6 +2334,7 @@ def mpl_connect(self, s, func):
- 'button_press_event'
- 'button_release_event'
- 'draw_event'
- 'pre_draw_event'
- 'key_press_event'
- 'key_release_event'
- 'motion_notify_event'
Expand Down
4 changes: 3 additions & 1 deletion lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -3268,7 +3268,6 @@ def draw(self, renderer):

with self._render_lock:

artists = self._get_draw_artists(renderer)
try:
renderer.open_group('figure', gid=self.get_gid())
if self.axes and self.get_layout_engine() is not None:
Expand All @@ -3278,6 +3277,9 @@ def draw(self, renderer):
pass
# ValueError can occur when resizing a window.

artists = self._get_draw_artists(renderer)
DrawEvent("pre_draw_event", self.canvas, renderer)._process()

self.patch.draw(renderer)
mimage._draw_list_compositing_images(
renderer, self, artists, self.suppressComposite)
Expand Down
61 changes: 61 additions & 0 deletions lib/matplotlib/tests/test_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1900,3 +1900,64 @@ def test_figsize_both_none():
def test_figsize_invalid_unit():
with pytest.raises(ValueError, match="Invalid unit 'um'"):
plt.figure(figsize=(6, 4, "um"))


def test_pre_draw_event_emitted():
fig, ax = plt.subplots()
count = []
fig.canvas.mpl_connect('pre_draw_event', lambda e: count.append(1))
fig.canvas.draw()
assert len(count) == 1


def test_pre_draw_event_before_draw_event():
fig, ax = plt.subplots()
order = []
fig.canvas.mpl_connect('pre_draw_event', lambda e: order.append('pre'))
fig.canvas.mpl_connect('draw_event', lambda e: order.append('draw'))
fig.canvas.draw()
assert order == ['pre', 'draw']


def test_pre_draw_event_axes_geometry_finalized():
fig, axs = plt.subplots(2, 2, constrained_layout=True)
for ax in axs.flat:
ax.plot([1, 2, 3], [1, 4, 2])

pre_positions = []
draw_positions = []

def on_pre(event):
pre_positions.extend(ax.get_position().bounds for ax in axs.flat)

def on_draw(event):
draw_positions.extend(ax.get_position().bounds for ax in axs.flat)

fig.canvas.mpl_connect('pre_draw_event', on_pre)
fig.canvas.mpl_connect('draw_event', on_draw)
fig.canvas.draw()

assert pre_positions == draw_positions


def test_pre_draw_event_inset_axes_geometry_finalized():
from mpl_toolkits.axes_grid1.inset_locator import inset_axes as make_inset

fig, ax = plt.subplots(constrained_layout=True)
ax.plot([1, 2, 3], [1, 4, 2])
inset = make_inset(ax, width='30%', height='30%', loc='upper right')
inset.plot([1, 2, 3], [3, 1, 2])

positions = {}

def on_pre(event):
positions['pre'] = inset.get_position().bounds

def on_draw(event):
positions['draw'] = inset.get_position().bounds

fig.canvas.mpl_connect('pre_draw_event', on_pre)
fig.canvas.mpl_connect('draw_event', on_draw)
fig.canvas.draw()

assert positions['pre'] == positions['draw']
2 changes: 1 addition & 1 deletion lib/matplotlib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"key_release_event"
]

DrawEventType: TypeAlias = Literal["draw_event"]
DrawEventType: TypeAlias = Literal["draw_event", "pre_draw_event"]
PickEventType: TypeAlias = Literal["pick_event"]
ResizeEventType: TypeAlias = Literal["resize_event"]
CloseEventType: TypeAlias = Literal["close_event"]
Expand Down
Loading