-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix marker overlap #10791
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix marker overlap #10791
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -455,18 +455,27 @@ def do_3d_projection(self, renderer): | |
|
||
fcs = (zalpha(self._facecolor3d, vzs) if self._depthshade else | ||
self._facecolor3d) | ||
fcs = mcolors.to_rgba_array(fcs, self._alpha) | ||
self.set_facecolors(fcs) | ||
|
||
ecs = (zalpha(self._edgecolor3d, vzs) if self._depthshade else | ||
self._edgecolor3d) | ||
|
||
# Sort the points based on z coordinates | ||
# Put vzs first to sort based on z value | ||
z_markers = sorted(zip(vzs, np.column_stack([vxs, vys]), fcs, ecs), | ||
reverse=True) | ||
|
||
[zzs, vps, fcs, ecs] = zip(*z_markers) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you'll need a check for an empty |
||
|
||
fcs = mcolors.to_rgba_array(fcs, self._alpha) | ||
ecs = mcolors.to_rgba_array(ecs, self._alpha) | ||
|
||
self.set_edgecolors(ecs) | ||
PathCollection.set_offsets(self, np.column_stack([vxs, vys])) | ||
self.set_facecolors(fcs) | ||
|
||
PathCollection.set_offsets(self, vps) | ||
|
||
if vzs.size > 0 : | ||
if vzs.size > 0: | ||
return min(vzs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't need to do |
||
else : | ||
else: | ||
return np.nan | ||
|
||
|
||
|
@@ -634,17 +643,16 @@ def do_3d_projection(self, renderer): | |
else: | ||
raise ValueError("whoops") | ||
|
||
segments_2d = [s for z, s, fc, ec, idx in z_segments_2d] | ||
[zzs, segments_2d, self._facecolors2d, self._edgecolors2d, idxs] = \ | ||
zip(*z_segments_2d) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. another check for empty |
||
|
||
if self._codes3d is not None: | ||
codes = [self._codes3d[idx] for z, s, fc, ec, idx in z_segments_2d] | ||
codes = [self._codes3d[idx] for idx in idxs] | ||
PolyCollection.set_verts_and_codes(self, segments_2d, codes) | ||
else: | ||
PolyCollection.set_verts(self, segments_2d, self._closed) | ||
|
||
self._facecolors2d = [fc for z, s, fc, ec, idx in z_segments_2d] | ||
if len(self._edgecolors3d) == len(cface): | ||
self._edgecolors2d = [ec for z, s, fc, ec, idx in z_segments_2d] | ||
else: | ||
if len(self._edgecolors3d) != len(cface): | ||
self._edgecolors2d = self._edgecolors3d | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. edgecolors3d hasn't been sorted, if I understand this correctly. |
||
|
||
# Return zorder value | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -175,6 +175,30 @@ def test_scatter3d_color(): | |
color='b', marker='s') | ||
|
||
|
||
@image_comparison(baseline_images=['scatter3d_overlap_markers_yellow'], | ||
extensions=['png'], remove_text=True) | ||
def test_overlap_markers_yellow_first(): | ||
fig = plt.figure() | ||
x = np.array([-1, 1]) | ||
y = np.array([1, -1]) | ||
z = np.array([0, 0]) | ||
ax = fig.add_subplot(111, projection='3d') | ||
patches = ax.scatter(x, y, z, s=3500, c=['b', 'y']) | ||
ax.view_init(elev=0, azim=-50) | ||
|
||
|
||
@image_comparison(baseline_images=['scatter3d_overlap_markers_blue'], | ||
extensions=['png'], remove_text=True) | ||
def test_overlap_markers_blue_first(): | ||
fig = plt.figure() | ||
x = np.array([-1, 1]) | ||
y = np.array([1, -1]) | ||
z = np.array([0, 0]) | ||
ax = fig.add_subplot(111, projection='3d') | ||
patches = ax.scatter(x, y, z, s=3500, c=['b', 'y']) | ||
ax.view_init(elev=0, azim=130) | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a bit more to these tests? Make sure the edge colors are getting sorted properly, too? |
||
@image_comparison(baseline_images=['plot_3d_from_2d'], remove_text=True, | ||
extensions=['png']) | ||
def test_plot_3d_from_2d(): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit worried that this could slow down the rendering when using many patches.
I know it's bad practice to base such an assumption on pure gut feeling. But before I'm going into any tests. Have you done benchmarking on the performance impact?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I had ran some benchmarking beforehand. I didn't notice any noticeable impact on performance.
I used the following script
Ran the script 5 times both before and after fix and didn't find any noticeable differences.
perf_fix.log
perf_vanilla.log
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These timings would have been swamped by all of the imports and figure creation and such. A real benchmark would involve seeing how long it would take to set up the plot, and then have it rotate around, like in one of the animation examples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a quick check on this part of the code, with numbers of points increased to 1000 000 (I think 100x100x100 is not unrealistic). With that the present sorting/zipping implementation is in the 100ms regime.
That's a size which gets relevant for performance in interactive use.
In a quick test, it's possible to get a roughly 10x speedup by using
numpy.argsort
on vzs and applying the index array to the other quantities.