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 8c3736f

Browse filesBrowse files
authored
Merge pull request #24491 from hukaidong/3dproj
Make Path3DCollection store indexed offset, and only apply z-ordered offset during draw
2 parents dc7b4f2 + 94e21bd commit 8c3736f
Copy full SHA for 8c3736f

File tree

2 files changed

+62
-3
lines changed
Filter options

2 files changed

+62
-3
lines changed

‎lib/mpl_toolkits/mplot3d/art3d.py

Copy file name to clipboardExpand all lines: lib/mpl_toolkits/mplot3d/art3d.py
+24-3Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
import numpy as np
1313

14+
from contextlib import contextmanager
15+
1416
from matplotlib import (
1517
artist, cbook, colors as mcolors, lines, text as mtext,
1618
path as mpath)
@@ -629,10 +631,12 @@ def __init__(self, *args, zs=0, zdir='z', depthshade=True, **kwargs):
629631
self._in_draw = False
630632
super().__init__(*args, **kwargs)
631633
self.set_3d_properties(zs, zdir)
634+
self._offset_zordered = None
632635

633636
def draw(self, renderer):
634-
with cbook._setattr_cm(self, _in_draw=True):
635-
super().draw(renderer)
637+
with self._use_zordered_offset():
638+
with cbook._setattr_cm(self, _in_draw=True):
639+
super().draw(renderer)
636640

637641
def set_sort_zpos(self, val):
638642
"""Set the position to use for z-sorting."""
@@ -731,15 +735,32 @@ def do_3d_projection(self):
731735
if len(self._linewidths3d) > 1:
732736
self._linewidths = self._linewidths3d[z_markers_idx]
733737

738+
PathCollection.set_offsets(self, np.column_stack((vxs, vys)))
739+
734740
# Re-order items
735741
vzs = vzs[z_markers_idx]
736742
vxs = vxs[z_markers_idx]
737743
vys = vys[z_markers_idx]
738744

739-
PathCollection.set_offsets(self, np.column_stack((vxs, vys)))
745+
# Store ordered offset for drawing purpose
746+
self._offset_zordered = np.column_stack((vxs, vys))
740747

741748
return np.min(vzs) if vzs.size else np.nan
742749

750+
@contextmanager
751+
def _use_zordered_offset(self):
752+
if self._offset_zordered is None:
753+
# Do nothing
754+
yield
755+
else:
756+
# Swap offset with z-ordered offset
757+
old_offset = self._offsets
758+
super().set_offsets(self._offset_zordered)
759+
try:
760+
yield
761+
finally:
762+
self._offsets = old_offset
763+
743764
def _maybe_depth_shade_and_sort_colors(self, color_array):
744765
color_array = (
745766
_zalpha(color_array, self._vzs)
+38Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import matplotlib.pyplot as plt
2+
3+
from matplotlib.backend_bases import MouseEvent
4+
5+
6+
def test_scatter_3d_projection_conservation():
7+
fig = plt.figure()
8+
ax = fig.add_subplot(projection='3d')
9+
# fix axes3d projection
10+
ax.roll = 0
11+
ax.elev = 0
12+
ax.azim = -45
13+
ax.stale = True
14+
15+
x = [0, 1, 2, 3, 4]
16+
scatter_collection = ax.scatter(x, x, x)
17+
fig.canvas.draw_idle()
18+
19+
# Get scatter location on canvas and freeze the data
20+
scatter_offset = scatter_collection.get_offsets()
21+
scatter_location = ax.transData.transform(scatter_offset)
22+
23+
# Yaw -44 and -46 are enough to produce two set of scatter
24+
# with opposite z-order without moving points too far
25+
for azim in (-44, -46):
26+
ax.azim = azim
27+
ax.stale = True
28+
fig.canvas.draw_idle()
29+
30+
for i in range(5):
31+
# Create a mouse event used to locate and to get index
32+
# from each dots
33+
event = MouseEvent("button_press_event", fig.canvas,
34+
*scatter_location[i, :])
35+
contains, ind = scatter_collection.contains(event)
36+
assert contains is True
37+
assert len(ind["ind"]) == 1
38+
assert ind["ind"][0] == i

0 commit comments

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