<h3 dir="auto">Bug summary</h3>
<p dir="auto">When plotting a surface and scatter points with <code class="notranslate">Axes3D</code>, either <em>none</em> of the scatter points are occluded by the surface or <em>all</em> of them are occluded.  Whether or not they are occluded appears to depend upon a numerical threshold. (Speculation: perhaps the occlusion of a single point?)</p>
<h3 dir="auto">Code for reproduction</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# On two separate plots, plot a surface and five lines via scatter3D.  
# The five lines are vertically offset by a constant.  
# The two separate plots differ by an imperceptible difference in offset.
# - The rendered difference is significant.
# - Neither is correct.

import numpy as np
import matplotlib.pyplot as plt

def surface(x, y):
  return np.sin(x) + 0.5 * y * np.cos(x)

def plot_surface_and_lines(vertical_line_offset):
  x, y = np.meshgrid(
    np.linspace(-5, 5, 100),
    np.linspace(-5, 5, 100),
  )

  fig = plt.figure(dpi=150)
  ax = fig.add_subplot(projection='3d')
  ax.set(
    xlabel='x',
    ylabel='y',
    zlim=(-3, 3),
    title=f'z offset = {vertical_line_offset}',
  )

  ax.plot_surface(x, y, surface(x, y))

  a, b = np.meshgrid(np.linspace(-5, 5, 5), np.linspace(-5, 5, 100))
  ax.scatter3D(a, b, surface(a, b) + vertical_line_offset, color='red')

  plt.show()


plot_surface_and_lines(0.253)
plot_surface_and_lines(0.254)"><pre class="notranslate"><span class="pl-c"># On two separate plots, plot a surface and five lines via scatter3D.  </span>
<span class="pl-c"># The five lines are vertically offset by a constant.  </span>
<span class="pl-c"># The two separate plots differ by an imperceptible difference in offset.</span>
<span class="pl-c"># - The rendered difference is significant.</span>
<span class="pl-c"># - Neither is correct.</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-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">def</span> <span class="pl-en">surface</span>(<span class="pl-s1">x</span>, <span class="pl-s1">y</span>):
  <span class="pl-k">return</span> <span class="pl-s1">np</span>.<span class="pl-en">sin</span>(<span class="pl-s1">x</span>) <span class="pl-c1">+</span> <span class="pl-c1">0.5</span> <span class="pl-c1">*</span> <span class="pl-s1">y</span> <span class="pl-c1">*</span> <span class="pl-s1">np</span>.<span class="pl-en">cos</span>(<span class="pl-s1">x</span>)

<span class="pl-k">def</span> <span class="pl-en">plot_surface_and_lines</span>(<span class="pl-s1">vertical_line_offset</span>):
  <span class="pl-s1">x</span>, <span class="pl-s1">y</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">meshgrid</span>(
    <span class="pl-s1">np</span>.<span class="pl-en">linspace</span>(<span class="pl-c1">-</span><span class="pl-c1">5</span>, <span class="pl-c1">5</span>, <span class="pl-c1">100</span>),
    <span class="pl-s1">np</span>.<span class="pl-en">linspace</span>(<span class="pl-c1">-</span><span class="pl-c1">5</span>, <span class="pl-c1">5</span>, <span class="pl-c1">100</span>),
  )

  <span class="pl-s1">fig</span> <span class="pl-c1">=</span> <span class="pl-s1">plt</span>.<span class="pl-en">figure</span>(<span class="pl-s1">dpi</span><span class="pl-c1">=</span><span class="pl-c1">150</span>)
  <span class="pl-s1">ax</span> <span class="pl-c1">=</span> <span class="pl-s1">fig</span>.<span class="pl-en">add_subplot</span>(<span class="pl-s1">projection</span><span class="pl-c1">=</span><span class="pl-s">'3d'</span>)
  <span class="pl-s1">ax</span>.<span class="pl-en">set</span>(
    <span class="pl-s1">xlabel</span><span class="pl-c1">=</span><span class="pl-s">'x'</span>,
    <span class="pl-s1">ylabel</span><span class="pl-c1">=</span><span class="pl-s">'y'</span>,
    <span class="pl-s1">zlim</span><span class="pl-c1">=</span>(<span class="pl-c1">-</span><span class="pl-c1">3</span>, <span class="pl-c1">3</span>),
    <span class="pl-s1">title</span><span class="pl-c1">=</span><span class="pl-s">f'z offset = <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">vertical_line_offset</span><span class="pl-kos">}</span></span>'</span>,
  )

  <span class="pl-s1">ax</span>.<span class="pl-en">plot_surface</span>(<span class="pl-s1">x</span>, <span class="pl-s1">y</span>, <span class="pl-en">surface</span>(<span class="pl-s1">x</span>, <span class="pl-s1">y</span>))

  <span class="pl-s1">a</span>, <span class="pl-s1">b</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">meshgrid</span>(<span class="pl-s1">np</span>.<span class="pl-en">linspace</span>(<span class="pl-c1">-</span><span class="pl-c1">5</span>, <span class="pl-c1">5</span>, <span class="pl-c1">5</span>), <span class="pl-s1">np</span>.<span class="pl-en">linspace</span>(<span class="pl-c1">-</span><span class="pl-c1">5</span>, <span class="pl-c1">5</span>, <span class="pl-c1">100</span>))
  <span class="pl-s1">ax</span>.<span class="pl-en">scatter3D</span>(<span class="pl-s1">a</span>, <span class="pl-s1">b</span>, <span class="pl-en">surface</span>(<span class="pl-s1">a</span>, <span class="pl-s1">b</span>) <span class="pl-c1">+</span> <span class="pl-s1">vertical_line_offset</span>, <span class="pl-s1">color</span><span class="pl-c1">=</span><span class="pl-s">'red'</span>)

  <span class="pl-s1">plt</span>.<span class="pl-en">show</span>()


<span class="pl-en">plot_surface_and_lines</span>(<span class="pl-c1">0.253</span>)
<span class="pl-en">plot_surface_and_lines</span>(<span class="pl-c1">0.254</span>)</pre></div>
<h3 dir="auto">Actual outcome</h3>
<kbd>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/1323521/177592539-65cdee1c-28aa-4d31-9783-be1b1b2e7fb5.png"><img src="https://user-images.githubusercontent.com/1323521/177592539-65cdee1c-28aa-4d31-9783-be1b1b2e7fb5.png" style="max-width: 100%;"></a>
</kbd>
<kbd>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/1323521/177592638-58cc892a-b208-431a-a777-2467319f6b52.png"><img src="https://user-images.githubusercontent.com/1323521/177592638-58cc892a-b208-431a-a777-2467319f6b52.png" style="max-width: 100%;"></a>
</kbd>
<h3 dir="auto">Expected outcome</h3>
<p dir="auto">Both plots should look like this, with occlusion determined point-by-point.</p>
<p dir="auto">(This was manually composited with an image editing tool, AFAICT this cannot be generated by matplotlib until the bug is fixed.)</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/1323521/177594193-100e0cb8-fcaf-42dd-8488-dad982db8fd0.png"><img src="https://user-images.githubusercontent.com/1323521/177594193-100e0cb8-fcaf-42dd-8488-dad982db8fd0.png" alt="image" style="max-width: 100%;"></a></p>
<h3 dir="auto">Additional information</h3>
<p dir="auto">This global occlusion occurs with many combinations of plots, not exclusively <code class="notranslate">.plot_surface</code> and <code class="notranslate">.scatter3D</code>.  The occluder or the occluded can be generated by any of</p>
<ul dir="auto">
<li><code class="notranslate">.plot_trisurf</code></li>
<li><code class="notranslate">.plot_surface</code></li>
<li><code class="notranslate">.scatter3D</code></li>
<li><code class="notranslate">.plot_wireframe</code><br>
and possibly others.  I did not test to find the numerical edge of occlusion/non-occlusion with the other combinations.</li>
</ul>
<p dir="auto">Perhaps this is related to other github issues related to depth testing or the underlying z-buffer.</p>
<h3 dir="auto">Operating system</h3>
<p dir="auto">Ubuntu 18.04.5 LTS, kernel 5.4.188+</p>
<h3 dir="auto">Matplotlib Version</h3>
<p dir="auto">3.2.2</p>
<h3 dir="auto">Matplotlib Backend</h3>
<p dir="auto">module://ipykernel.pylab.backend_inline</p>
<h3 dir="auto">Python version</h3>
<p dir="auto">3.7.13</p>
<h3 dir="auto">Jupyter version</h3>
<p dir="auto">5.3.1 (via google colab release 2022/6/10)</p>
<h3 dir="auto">Installation</h3>
<p dir="auto"><em>No response</em></p>
<h3 dir="auto">Bug summary</h3>
<p dir="auto">wspace parameter does not work using <code class="notranslate">fig.subfigures()</code> <strong>without constrained layout</strong>.</p>
<h3 dir="auto">Code for reproduction</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="fig = plt.figure(figsize=(20, 14))
subfigs = fig.subfigures(1, 4, wspace=0.5, width_ratios=[0.5, 1, 1, 1])

axs0= subfigs[0].subplots(nrows = 12, ncols = 1, sharex = True)
axs1 = subfigs[1].subplots(nrows = 12, ncols = 1, sharex = True)
subfigs[1].suptitle('\n A subfigure')

axs2 = subfigs[2].subplots(nrows = 12, ncols = 1, sharex = True)
subfigs[2].suptitle('\n A subfigure')

axs3 = subfigs[3].subplots(nrows = 12, ncols = 1, sharex = True)
subfigs[3].suptitle('\n A subfigure')"><pre class="notranslate"><span class="pl-s1">fig</span> <span class="pl-c1">=</span> <span class="pl-s1">plt</span>.<span class="pl-en">figure</span>(<span class="pl-s1">figsize</span><span class="pl-c1">=</span>(<span class="pl-c1">20</span>, <span class="pl-c1">14</span>))
<span class="pl-s1">subfigs</span> <span class="pl-c1">=</span> <span class="pl-s1">fig</span>.<span class="pl-en">subfigures</span>(<span class="pl-c1">1</span>, <span class="pl-c1">4</span>, <span class="pl-s1">wspace</span><span class="pl-c1">=</span><span class="pl-c1">0.5</span>, <span class="pl-s1">width_ratios</span><span class="pl-c1">=</span>[<span class="pl-c1">0.5</span>, <span class="pl-c1">1</span>, <span class="pl-c1">1</span>, <span class="pl-c1">1</span>])

<span class="pl-s1">axs0</span><span class="pl-c1">=</span> <span class="pl-s1">subfigs</span>[<span class="pl-c1">0</span>].<span class="pl-en">subplots</span>(<span class="pl-s1">nrows</span> <span class="pl-c1">=</span> <span class="pl-c1">12</span>, <span class="pl-s1">ncols</span> <span class="pl-c1">=</span> <span class="pl-c1">1</span>, <span class="pl-s1">sharex</span> <span class="pl-c1">=</span> <span class="pl-c1">True</span>)
<span class="pl-s1">axs1</span> <span class="pl-c1">=</span> <span class="pl-s1">subfigs</span>[<span class="pl-c1">1</span>].<span class="pl-en">subplots</span>(<span class="pl-s1">nrows</span> <span class="pl-c1">=</span> <span class="pl-c1">12</span>, <span class="pl-s1">ncols</span> <span class="pl-c1">=</span> <span class="pl-c1">1</span>, <span class="pl-s1">sharex</span> <span class="pl-c1">=</span> <span class="pl-c1">True</span>)
<span class="pl-s1">subfigs</span>[<span class="pl-c1">1</span>].<span class="pl-en">suptitle</span>(<span class="pl-s">'<span class="pl-cce">\n</span> A subfigure'</span>)

<span class="pl-s1">axs2</span> <span class="pl-c1">=</span> <span class="pl-s1">subfigs</span>[<span class="pl-c1">2</span>].<span class="pl-en">subplots</span>(<span class="pl-s1">nrows</span> <span class="pl-c1">=</span> <span class="pl-c1">12</span>, <span class="pl-s1">ncols</span> <span class="pl-c1">=</span> <span class="pl-c1">1</span>, <span class="pl-s1">sharex</span> <span class="pl-c1">=</span> <span class="pl-c1">True</span>)
<span class="pl-s1">subfigs</span>[<span class="pl-c1">2</span>].<span class="pl-en">suptitle</span>(<span class="pl-s">'<span class="pl-cce">\n</span> A subfigure'</span>)

<span class="pl-s1">axs3</span> <span class="pl-c1">=</span> <span class="pl-s1">subfigs</span>[<span class="pl-c1">3</span>].<span class="pl-en">subplots</span>(<span class="pl-s1">nrows</span> <span class="pl-c1">=</span> <span class="pl-c1">12</span>, <span class="pl-s1">ncols</span> <span class="pl-c1">=</span> <span class="pl-c1">1</span>, <span class="pl-s1">sharex</span> <span class="pl-c1">=</span> <span class="pl-c1">True</span>)
<span class="pl-s1">subfigs</span>[<span class="pl-c1">3</span>].<span class="pl-en">suptitle</span>(<span class="pl-s">'<span class="pl-cce">\n</span> A subfigure'</span>)</pre></div>
<h3 dir="auto">Actual outcome</h3>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/64196642/226391637-ccb126ff-c20e-4fbd-8fda-f6e599942c75.png"><img src="https://user-images.githubusercontent.com/64196642/226391637-ccb126ff-c20e-4fbd-8fda-f6e599942c75.png" alt="image" style="max-width: 100%;"></a><br>
This is the output. It is the same regardless of the wspace parameter given.</p>
<h3 dir="auto">Expected outcome</h3>
<p dir="auto">I would expect more space between each subfigure, since we used wspace = 0.5<br>
If I change this parameter, nothing changes.</p>
<h3 dir="auto">Additional information</h3>
<p dir="auto">Maybe the bug is happening because the wspace is modifying the space between subplots, and not between subfigures ?</p>
<h3 dir="auto">Operating system</h3>
<p dir="auto">Ubuntu</p>
<h3 dir="auto">Matplotlib Version</h3>
<p dir="auto">3.6.2</p>
<h3 dir="auto">Matplotlib Backend</h3>
<p dir="auto">Qt5Agg</p>
<h3 dir="auto">Python version</h3>
<p dir="auto">3.10.9</p>
<h3 dir="auto">Jupyter version</h3>
<p dir="auto"><em>No response</em></p>
<h3 dir="auto">Installation</h3>
<p dir="auto">conda</p>