Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 94e21bd

Browse files
committed
Path3DCollection restore vert orders after draw() and index conservation test
1 parent 57710db commit 94e21bd

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

lib/mpl_toolkits/mplot3d/art3d.py

Lines 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)
Lines 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)