<h3 dir="auto">Bug report</h3>
<p dir="auto"><strong>Bug summary</strong></p>
<p dir="auto">The axes of a subplot_mosaic show up in a random order in <code class="notranslate">fig.axes</code> (likely due to the use of a <code class="notranslate">set</code> for uniquification in <code class="notranslate">_identify_keys_and_nested</code>).</p>
<p dir="auto"><strong>Code for reproduction</strong></p>

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="for _ in $(seq 10); do python -c 'from pylab import *; fig, axs = subplot_mosaic(&quot;ab&quot;); print(fig.axes.index(axs[&quot;a&quot;]))'; done"><pre class="notranslate"><span class="pl-k">for</span> <span class="pl-smi">_</span> <span class="pl-k">in</span> <span class="pl-s"><span class="pl-pds">$(</span>seq 10<span class="pl-pds">)</span></span><span class="pl-k">;</span> <span class="pl-k">do</span> python -c <span class="pl-s"><span class="pl-pds">'</span>from pylab import *; fig, axs = subplot_mosaic("ab"); print(fig.axes.index(axs["a"]))<span class="pl-pds">'</span></span><span class="pl-k">;</span> <span class="pl-k">done</span></pre></div>
<p dir="auto"><strong>Actual outcome</strong></p>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="1
0
1
1
1
0
0
0
0
1"><pre class="notranslate"><code class="notranslate">1
0
1
1
1
0
0
0
0
1
</code></pre></div>
<p dir="auto"><strong>Expected outcome</strong></p>
<p dir="auto">Axes should be added in a consistent order.  I guess a reasonable one would be as if iterating the spec in C order (dropping duplicates).</p>
<p dir="auto">Not release critical (especially as the order was not fixed, so fixing an order is not a backcompat break), but would be nice to get this sorted out before the API moves out of being experimental.</p>
<p dir="auto"><strong>Matplotlib version</strong></p>

<ul dir="auto">
<li>Operating system: linux</li>
<li>Matplotlib version (<code class="notranslate">import matplotlib; print(matplotlib.__version__)</code>): head</li>
<li>Matplotlib backend (<code class="notranslate">print(matplotlib.get_backend())</code>): any</li>
<li>Python version: 39</li>
<li>Jupyter version (if applicable):</li>
<li>Other libraries:</li>
</ul>


<hr>
<p dir="auto">Note: the simple solution of replacing <code class="notranslate">unique_ids = set()</code> by <code class="notranslate">unique_ids = cbook._OrderedSet()</code> is good enough for the non-nested case, but doesn't handle nested layouts such as <code class="notranslate">subplot_mosaic([["a", [["b1", "b2"], ["b3", "b4"]]], ["c", "d"]])</code> because currently the nested submosaic is always added after all the non-nested axes.</p>
<p dir="auto">Consider the following example:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import matplotlib.pyplot as plt
import numpy as np

fig,axes = plt.subplots()
line_A = axes.plot( np.random.random(10), label=&quot;foo&quot; )[0]
line_B = axes.plot( np.random.random(10), label=&quot;bar&quot; )[0]
line_C = axes.plot( np.random.random(10), label=&quot;quz&quot; )[0]
lines = [line_A,line_B]

axes.legend( lines, [line.get_label() for line in lines] )"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">matplotlib</span>.<span class="pl-s1">pyplot</span> <span class="pl-k">as</span> <span class="pl-s1">plt</span>
<span class="pl-k">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>

<span class="pl-s1">fig</span>,<span class="pl-s1">axes</span> <span class="pl-c1">=</span> <span class="pl-s1">plt</span>.<span class="pl-en">subplots</span>()
<span class="pl-s1">line_A</span> <span class="pl-c1">=</span> <span class="pl-s1">axes</span>.<span class="pl-en">plot</span>( <span class="pl-s1">np</span>.<span class="pl-s1">random</span>.<span class="pl-en">random</span>(<span class="pl-c1">10</span>), <span class="pl-s1">label</span><span class="pl-c1">=</span><span class="pl-s">"foo"</span> )[<span class="pl-c1">0</span>]
<span class="pl-s1">line_B</span> <span class="pl-c1">=</span> <span class="pl-s1">axes</span>.<span class="pl-en">plot</span>( <span class="pl-s1">np</span>.<span class="pl-s1">random</span>.<span class="pl-en">random</span>(<span class="pl-c1">10</span>), <span class="pl-s1">label</span><span class="pl-c1">=</span><span class="pl-s">"bar"</span> )[<span class="pl-c1">0</span>]
<span class="pl-s1">line_C</span> <span class="pl-c1">=</span> <span class="pl-s1">axes</span>.<span class="pl-en">plot</span>( <span class="pl-s1">np</span>.<span class="pl-s1">random</span>.<span class="pl-en">random</span>(<span class="pl-c1">10</span>), <span class="pl-s1">label</span><span class="pl-c1">=</span><span class="pl-s">"quz"</span> )[<span class="pl-c1">0</span>]
<span class="pl-s1">lines</span> <span class="pl-c1">=</span> [<span class="pl-s1">line_A</span>,<span class="pl-s1">line_B</span>]

<span class="pl-s1">axes</span>.<span class="pl-en">legend</span>( <span class="pl-s1">lines</span>, [<span class="pl-s1">line</span>.<span class="pl-en">get_label</span>() <span class="pl-k">for</span> <span class="pl-s1">line</span> <span class="pl-c1">in</span> <span class="pl-s1">lines</span>] )</pre></div>
<p dir="auto">The last line needs to be this complicated since I get unwanted internal information if I just use <code class="notranslate">axes.legend(lines)</code>. However, this seems like something <code class="notranslate">legend</code> could do automatically: If I do not specify the handles for the legend, it extracts them from whatever I give it automatically.</p>
<p dir="auto">This may be a duplicate of <a href="https://github.com/matplotlib/matplotlib/issues/8389" data-hovercard-type="issue" data-hovercard-url="/matplotlib/matplotlib/issues/8389/hovercard">this request</a>, but I am not sure.</p>