Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cc10355

Browse filesBrowse files
authored
Merge pull request #17378 from timhoffm/fix-marker-overlap2
FIX: marker overlap order in 3D scatter
2 parents a6f82b9 + 4428da6 commit cc10355
Copy full SHA for cc10355

File tree

Expand file treeCollapse file tree

2 files changed

+69
-7
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+69
-7
lines changed

‎lib/mpl_toolkits/mplot3d/art3d.py

Copy file name to clipboardExpand all lines: lib/mpl_toolkits/mplot3d/art3d.py
+24-7Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,27 @@ def do_3d_projection(self, renderer):
494494

495495
ecs = (_zalpha(self._edgecolor3d, vzs) if self._depthshade else
496496
self._edgecolor3d)
497+
498+
# Sort the points based on z coordinates
499+
# Performance optimization: Create a sorted index array and reorder
500+
# points and point properties according to the index array
501+
z_markers_idx = np.argsort(vzs)[::-1]
502+
503+
# Re-order items
504+
vzs = vzs[z_markers_idx]
505+
vxs = vxs[z_markers_idx]
506+
vys = vys[z_markers_idx]
507+
fcs = fcs[z_markers_idx]
508+
ecs = ecs[z_markers_idx]
509+
vps = np.column_stack((vxs, vys))
510+
511+
fcs = mcolors.to_rgba_array(fcs, self._alpha)
497512
ecs = mcolors.to_rgba_array(ecs, self._alpha)
513+
498514
self.set_edgecolors(ecs)
499-
PathCollection.set_offsets(self, np.column_stack([vxs, vys]))
515+
self.set_facecolors(fcs)
516+
517+
PathCollection.set_offsets(self, vps)
500518

501519
return np.min(vzs) if vzs.size else np.nan
502520

@@ -663,17 +681,16 @@ def do_3d_projection(self, renderer):
663681
in enumerate(zip(xyzlist, cface, cedge))),
664682
key=lambda x: x[0], reverse=True)
665683

666-
segments_2d = [s for z, s, fc, ec, idx in z_segments_2d]
684+
zzs, segments_2d, self._facecolors2d, self._edgecolors2d, idxs = \
685+
zip(*z_segments_2d)
686+
667687
if self._codes3d is not None:
668-
codes = [self._codes3d[idx] for z, s, fc, ec, idx in z_segments_2d]
688+
codes = [self._codes3d[idx] for idx in idxs]
669689
PolyCollection.set_verts_and_codes(self, segments_2d, codes)
670690
else:
671691
PolyCollection.set_verts(self, segments_2d, self._closed)
672692

673-
self._facecolors2d = [fc for z, s, fc, ec, idx in z_segments_2d]
674-
if len(self._edgecolors3d) == len(cface):
675-
self._edgecolors2d = [ec for z, s, fc, ec, idx in z_segments_2d]
676-
else:
693+
if len(self._edgecolors3d) != len(cface):
677694
self._edgecolors2d = self._edgecolors3d
678695

679696
# Return zorder value

‎lib/mpl_toolkits/tests/test_mplot3d.py

Copy file name to clipboardExpand all lines: lib/mpl_toolkits/tests/test_mplot3d.py
+45Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,51 @@ def test_scatter3d_color():
230230
color='b', marker='s')
231231

232232

233+
@pytest.mark.parametrize('azim', [-50, 130]) # yellow first, blue first
234+
@check_figures_equal(extensions=['png'])
235+
def test_marker_draw_order_data_reversed(fig_test, fig_ref, azim):
236+
"""
237+
Test that the draw order does not depend on the data point order.
238+
239+
For the given viewing angle at azim=-50, the yellow marker should be in
240+
front. For azim=130, the blue marker should be in front.
241+
"""
242+
x = [-1, 1]
243+
y = [1, -1]
244+
z = [0, 0]
245+
color = ['b', 'y']
246+
ax = fig_test.add_subplot(projection='3d')
247+
ax.scatter(x, y, z, s=3500, c=color)
248+
ax.view_init(elev=0, azim=azim)
249+
ax = fig_ref.add_subplot(projection='3d')
250+
ax.scatter(x[::-1], y[::-1], z[::-1], s=3500, c=color[::-1])
251+
ax.view_init(elev=0, azim=azim)
252+
253+
254+
@check_figures_equal(extensions=['png'])
255+
def test_marker_draw_order_view_rotated(fig_test, fig_ref):
256+
"""
257+
Test that the draw order changes with the direction.
258+
259+
If we rotate *azim* by 180 degrees and exchange the colors, the plot
260+
plot should look the same again.
261+
"""
262+
azim = 130
263+
x = [-1, 1]
264+
y = [1, -1]
265+
z = [0, 0]
266+
color = ['b', 'y']
267+
ax = fig_test.add_subplot(projection='3d')
268+
# axis are not exactly invariant under 180 degree rotation -> deactivate
269+
ax.set_axis_off()
270+
ax.scatter(x, y, z, s=3500, c=color)
271+
ax.view_init(elev=0, azim=azim)
272+
ax = fig_ref.add_subplot(projection='3d')
273+
ax.set_axis_off()
274+
ax.scatter(x, y, z, s=3500, c=color[::-1]) # color reversed
275+
ax.view_init(elev=0, azim=azim - 180) # view rotated by 180 degrees
276+
277+
233278
@mpl3d_image_comparison(['plot_3d_from_2d.png'], tol=0.01)
234279
def test_plot_3d_from_2d():
235280
fig = plt.figure()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.