Skip to content

PERF: More speedups#31004

Merged
QuLogic merged 9 commits into
matplotlib:mainfrom
scottshambaugh:more_speedups
Mar 6, 2026
Merged

PERF: More speedups#31004
QuLogic merged 9 commits into
matplotlib:mainfrom
scottshambaugh:more_speedups

Conversation

@scottshambaugh

@scottshambaugh scottshambaugh commented Jan 20, 2026

Copy link
Copy Markdown
Contributor

PR summary

A collection of a few more speedups from profiling large 2D line, scatter, and fill_between plots. I didn't record my profiling runs for all these changes, but saw a ~40% speedup for a plot with 100x 5000-point lines.

  • Bbox.update_from_path gets another fast path
  • The other updates are all variations on avoiding extra numpy array copy operations

PR checklist

Comment thread lib/matplotlib/collections.py Outdated
Comment thread lib/matplotlib/collections.py Outdated

@timhoffm timhoffm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a general feedback, I'm somewhat hesitant on the changes. While I believe your overall profiling and speed-up claims, I'm unclear which changes contribute in which amount.

Typically, the changes here come with increased code complexity and lower readability. Therefore, I would like to only include the changes that really matter.

Comment thread lib/matplotlib/collections.py Outdated
Comment thread lib/matplotlib/axes/_base.py Outdated
Comment thread lib/matplotlib/axes/_base.py Outdated
@scottshambaugh

scottshambaugh commented Feb 2, 2026

Copy link
Copy Markdown
Contributor Author

I cleaned some stuff up, the remaining changes are all impactful (across different profiler cases, this is a bit of a grab-bag of updates so difficult to show one script with a clean difference).

I think the one borderline decision is putting in a sentinel case for STEP_LOOKUP_MAP. We do skip an array creation with two transposes, which comes out to 1% of total draw time and 5% of Line2d.recache() function time for the below script. But it requires adding special handling for the sentinel cases. I'll defer to your call on if that's worth it.

import time
import numpy as np
import matplotlib.pyplot as plt

print("Starting...")
fig, ax = plt.subplots()
x = y = np.linspace(-1, 1, 10000)

print("Timing...")
start_time = time.perf_counter()
for i in range(1000):
    ax.plot(x + i, y)
fig.canvas.draw()
end_time = time.perf_counter()

plt.close()
print(f"Time taken: {end_time - start_time:.4f} seconds")

Comment thread lib/matplotlib/collections.py Outdated
Comment thread lib/matplotlib/lines.py Outdated
Comment thread lib/matplotlib/lines.py Outdated
Comment thread lib/matplotlib/transforms.py Outdated

@timhoffm timhoffm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make cbook.STEP_LOOKUP_MAP private and eventually remove the "default" key since we don't use it anymore in our code. But that's a cleanup that can be done in a separte PR.

Comment thread lib/matplotlib/collections.py Outdated
Comment thread lib/matplotlib/collections.py Outdated
@QuLogic QuLogic merged commit fb6ca2d into matplotlib:main Mar 6, 2026
40 checks passed
@QuLogic QuLogic added this to the v3.11.0 milestone Mar 6, 2026
@scottshambaugh scottshambaugh mentioned this pull request Mar 6, 2026
1 task
andreas16700 added a commit to andreas16700/matplotlib that referenced this pull request Mar 16, 2026
andreas16700 added a commit to andreas16700/matplotlib that referenced this pull request Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants