<p dir="auto">matplotlib 1.5.3, Python 2.7.3, Linux (Ubuntu 14.04 LTS), installed using pip</p>
<p dir="auto"><code class="notranslate">pyplot.subplots()</code> is significantly slower than <code class="notranslate">pyplot.subplot()</code>. This becomes significant when plotting a large number of subplots. For example <code class="notranslate">subplots(40)</code> takes 2.3s whereas 40 calls to <code class="notranslate">subplot()</code> with differing parameters just take 25ms.</p>
<p dir="auto">Minimal example (using ipython):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import matplotlib.pyplot as plt
%timeit plt.subplots(40)"><pre class="notranslate"><code class="notranslate">import matplotlib.pyplot as plt
%timeit plt.subplots(40)
</code></pre></div>
<ul dir="auto">
<li>The effect does not depend on the grid: 40x1 is the same as 5x8.</li>
<li>The time needed increases linearly with the number of subplots.</li>
<li>The effect does not seem to depend on the parameters <code class="notranslate">sharex</code>, <code class="notranslate">sharey</code> and <code class="notranslate">squeeze</code> (though I have not tested all possible parameters)</li>
<li>profiling the call reveals that there are a lot of calls to <code class="notranslate">reset_ticks</code>, which use up 75% of the time. See the runsnake screenshot below:</li>
</ul>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://cloud.githubusercontent.com/assets/2836374/18766172/2920a28c-8119-11e6-95a8-99a4c0d15c76.png"><img src="https://cloud.githubusercontent.com/assets/2836374/18766172/2920a28c-8119-11e6-95a8-99a4c0d15c76.png" alt="matplotlib_subplots40" style="max-width: 100%;"></a></p>
<p dir="auto">It seems there is a lot of unneccesary(?) clearing happening. Would it be possible to speed this up?</p>
<div class="highlight highlight-source-batchfile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt; python -V
Python 2.7.11
&gt; pip freeze | grep matplotlib
matplotlib==1.5.1
&gt; python -m platform -s &quot;print platform()&quot;
Windows-7-6.1.7601-SP2"><pre class="notranslate"><span class="pl-k">&gt;</span> python -V
Python 2.7.11
<span class="pl-k">&gt;</span> pip freeze <span class="pl-k">|</span> grep matplotlib
matplotlib<span class="pl-k">==</span>1.5.1
<span class="pl-k">&gt;</span> python -m platform -s <span class="pl-s"><span class="pl-pds">"</span>print platform()<span class="pl-pds">"</span></span>
Windows-7-6.1.7601-SP2</pre></div>
<p dir="auto">I have discovered that my application spends a lot of time in Axes creation. Results of class instantiation profiling is below:</p>
<div class="highlight highlight-source-batchfile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt; python -m timeit -s &quot;from matplotlib.figure import Figure; from matplotlib.axes import Axes; fig = Figure()&quot; &quot;Axes(fig, (0, 0, 1 ,1))&quot;
10 loops, best of 3: 33.2 msec per loop"><pre class="notranslate"><span class="pl-k">&gt;</span> python -m timeit -s <span class="pl-s"><span class="pl-pds">"</span>from matplotlib.figure import Figure; from matplotlib.axes import Axes; fig = Figure()<span class="pl-pds">"</span></span> <span class="pl-s"><span class="pl-pds">"</span>Axes(fig, (0, 0, 1 ,1))<span class="pl-pds">"</span></span>
<span class="pl-c1">10</span> loops, best of 3: 33.2 msec per loop</pre></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://cloud.githubusercontent.com/assets/2743474/16426952/dd5ff57a-3d73-11e6-91c3-7483ec1b82be.png"><img src="https://cloud.githubusercontent.com/assets/2743474/16426952/dd5ff57a-3d73-11e6-91c3-7483ec1b82be.png" alt="axes-compressor" style="max-width: 100%;"></a><br>
Inside <code class="notranslate">Axes.__init__</code> most of the execution time takes <code class="notranslate">self.cla()</code> call and about the half of it is<br>
<a href="https://github.com/matplotlib/matplotlib/blob/a8ad349c583b79ee24e749497381ab026ac5a360/lib/matplotlib/axes/_base.py#L952-L953">this loop below</a></p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="        for name, spine in six.iteritems(self.spines):
            spine.cla()"><pre class="notranslate">        <span class="pl-k">for</span> <span class="pl-s1">name</span>, <span class="pl-s1">spine</span> <span class="pl-c1">in</span> <span class="pl-s1">six</span>.<span class="pl-en">iteritems</span>(<span class="pl-s1">self</span>.<span class="pl-s1">spines</span>):
            <span class="pl-s1">spine</span>.<span class="pl-en">cla</span>()</pre></div>
<p dir="auto">After commenting this two lines I have got this:</p>
<div class="highlight highlight-source-batchfile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt; python -m timeit -s &quot;from matplotlib.figure import Figure; from matplotlib.axes import Axes; fig = Figure()&quot; &quot;Axes(fig, (0, 0, 1 ,1))&quot;
100 loops, best of 3: 17.9 msec per loop"><pre class="notranslate"><span class="pl-k">&gt;</span> python -m timeit -s <span class="pl-s"><span class="pl-pds">"</span>from matplotlib.figure import Figure; from matplotlib.axes import Axes; fig = Figure()<span class="pl-pds">"</span></span> <span class="pl-s"><span class="pl-pds">"</span>Axes(fig, (0, 0, 1 ,1))<span class="pl-pds">"</span></span>
<span class="pl-c1">100</span> loops, best of 3: 17.9 msec per loop</pre></div>
<p dir="auto">So we have 33 ms per axes creation, and the half of this time it is used for spines creation that actually may be not used (in my case I have bunch of sharex axes and only one of them have spines).<br>
I see a possible solution where creation of spines, scales (you can see creation of logarithmic scale, which I do not use too) and other stuff is delayed to the point when it actually needed/initialized.</p>
<p dir="auto">And the fun part. For 20 created Axes we have 60115 calls to <code class="notranslate">Rectangle.stale</code> (3005 call per Axes instantiation)<br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://cloud.githubusercontent.com/assets/2743474/16427532/6695645e-3d76-11e6-9106-2226cbac1338.png"><img src="https://cloud.githubusercontent.com/assets/2743474/16427532/6695645e-3d76-11e6-9106-2226cbac1338.png" alt="image" style="max-width: 100%;"></a></p>