Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Improve performance of plt.clf() #26243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed

Conversation

eendebakpt
Copy link
Contributor

@eendebakpt eendebakpt commented Jul 3, 2023

PR summary

This PR improves performance of plt.clf(). By setting spines.axis to None a double call to XAxis.clear() and YAxis.clear() is avoided.

Benchmark script:

import time
import matplotlib
from matplotlib import axis
import matplotlib.pyplot as plt
print(matplotlib.__version__)

def go():
	t0=time.perf_counter()
	for ii in range(5):
		plt.figure(100)
		plt.clf()
		plt.plot(range(20), range(20,40), label='hi')
		plt.legend()
		
	dt=time.perf_counter()	-t0
	return dt
	
niter=10
x=[]
for ii in range(niter):
    dt=go()	
    print(f'round {ii}: {dt:2f} [s]')
    x.append(dt)
    
print(f'mean: {sum(x)/niter:.2f} [s]')    

Performance on main:

3.8.0.dev1461+gf017315dd5
round 0: 0.329322 [s]
round 1: 0.173158 [s]
round 2: 0.196067 [s]
round 3: 0.167451 [s]
round 4: 0.170085 [s]
round 5: 0.169859 [s]
round 6: 0.203656 [s]
round 7: 0.167369 [s]
round 8: 0.170247 [s]
round 9: 0.166873 [s]
mean: 0.19 [s]

Performance on PR

3.8.0.dev1463+gbff26576f7
round 0: 0.276565 [s]
round 1: 0.088187 [s]
round 2: 0.089832 [s]
round 3: 0.089987 [s]
round 4: 0.111984 [s]
round 5: 0.089566 [s]
round 6: 0.086931 [s]
round 7: 0.087903 [s]
round 8: 0.090093 [s]
round 9: 0.085896 [s]
mean: 0.11 [s]

Also see #23771

PR checklist

  • [N/A] "closes #0000" is in the body of the PR description to link the related issue. Issue is mentioned, but this PR does not fully address the issue.
  • new and changed code is tested
  • [N/A ] Plotting related features are demonstrated in an example
  • [N/A] New Features and API Changes are noted with a directive and release note
  • [N/A] Documentation complies with general and docstring guidelines

@tacaswell
Copy link
Member

Where does the axis on the spine get re-set to not None?

@eendebakpt
Copy link
Contributor Author

Where does the axis on the spine get re-set to not None?

Thanks for the quick review, resetting the spine is indeed necessary. Not sure whether this is enough (I am still setting up tests locally), but the performance improvement seems worthwhile.

@oscargus
Copy link
Member

oscargus commented Jul 4, 2023

I'd just like to point out #26164.

@eendebakpt eendebakpt changed the title Draft: improve performance of plt.clf() Improve performance of plt.clf() Jul 4, 2023
@eendebakpt
Copy link
Contributor Author

@tacaswell Tests are passing now. The PR assumes the axis in the spines objects are the same as in self._axis_map. If this is not always the case, we could also do something like:

        cleared_axis = list( self._axis_map.values() )
        for spine in self.spines.values():
            # avoid expensive methods in the clearing of the spine, gh-26243            
            tmp_axis = spine.axis
            if tmp_axis in cleared_axis:
                spine.axis = None
            else:
                 cleared_axis.append(tmp_axis)
            spine.clear()
            spine.axis = tmp_axis

@@ -1275,7 +1275,11 @@ def __clear(self):
for axis in self._axis_map.values():
axis.clear() # Also resets the scale to linear.
for spine in self.spines.values():
# avoid expensive methods in the clearing of the spine, gh-26243
tmp_axis = spine.axis
spine.axis = None
Copy link
Member

Choose a reason for hiding this comment

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

We have a context manager that will do this setting/resetting in matplotlib.cbook._setattr_cm.

@tacaswell
Copy link
Member

@eendebakpt I think that the way this is addressed in #26164 is a better way to address this as it avoids patching monkeying with spine state (at the cost of a new private method).

@eendebakpt
Copy link
Contributor Author

@eendebakpt I think that the way this is addressed in #26164 is a better way to address this as it avoids patching monkeying with spine state (at the cost of a new private method).

I tested #26164 with the benchmark script from this PR and the performance gain is comparable. If that PR is merged, I will close this one.

@eendebakpt
Copy link
Contributor Author

Closing in favor of #26164

@eendebakpt eendebakpt closed this Jul 8, 2023
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.

4 participants