Skip to content

Axes3D/add_collection3D( LineCollection ): Z-Index forces incorrect drawing order #3884

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

Open
demisjohn opened this issue Dec 4, 2014 · 6 comments
Labels
keep Items to be ignored by the “Stale” Github Action topic: mplot3d

Comments

@demisjohn
Copy link

Hello,
I believe I have found a bug in using add_collection3d() to produce plots like in this example:
'Matplotlib Tutorial / Polygon plots / Axes3D.add_collection3d' -- sorry, you have to click "Polygon Plots" due to the page's inability to target properly
(The actual demo script is here. )
The bug is exhibited when you use a LineCollection instead of PolyCollection (the example uses PolyCollection)

My guess is that, for a 3DLineCollection, the Z-Index controls the drawing order, such that the highest valued Z-Index is always obscured by the lower-valued Z-indices, even when you rotate the plot (azimuth angle).

I have modified the aforementioned PolyCollection example (which is bugless) to plot the same data via a LineCollection instead, which immediately reproduces the plotting issue.

Here is the example of a Collection3D of a LineCollection (note the viewing Azimuth angle), rotated to look as expected, with the appropriate Lines obscuring those behind them:
screen shot 2014-12-03 at 9 19 15 pm

However, with the plot rotated 90 degrees (Azimuthal angle), we get an Incorrect drawing (the Yellow curves should be at the Back):
screen shot 2014-12-03 at 9 19 20 pm

To reiterate, this problem does Not occur with a PolyCollection passed to add_collection3d(), but does when passing a LineCollection.

Please let me know if you're able to reproduce the problem, and thanks for your time & patience with a first-time poster.

Here is the aforementioned example script, modified to plot a LineCollection instead (and alpha set to 1.0 to aid visual clarity).


from mpl_toolkits.mplot3d import Axes3D
from matplotlib.collections import LineCollection   # was `PolyCollection`
from matplotlib.colors import colorConverter
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.gca(projection='3d')

alpha_=1.0  # to accentuate the issue

cc = lambda arg: colorConverter.to_rgba(arg, alpha=alpha_)

xs = np.arange(0, 10, 0.4)
verts = []
zs = [0.0, 1.0, 2.0, 3.0]
for z in zs:
    ys = np.random.rand(len(xs))
    ys[0], ys[-1] = 0, 0
    verts.append(list(zip(xs, ys)))

poly = LineCollection(verts, facecolor = [cc('r'), cc('g'), cc('b'),
                                           cc('y')])   # was `PolyCollection`, and `facecolor` was `facecolors`
poly.set_alpha(alpha_)
ax.add_collection3d(poly, zs=zs, zdir='y')

ax.set_xlabel('X')
ax.set_xlim3d(0, 10)
ax.set_ylabel('Y')
ax.set_ylim3d(-1, 4)
ax.set_zlabel('Z')
ax.set_zlim3d(0, 1)

plt.show()
@tacaswell tacaswell added this to the unassigned milestone Dec 4, 2014
@WeatherGod
Copy link
Member

Indeed, there is a bug, but it isn't quite like what you think is happening. The collection object gets a single zorder value in order to determine its drawing order in relation to other artists, but it is up to the collection object to determine the draw order for its own elements. This is the best we can do given Matplotlib's layering engine for rendering.

The Poly3DCollection has some sophisticated logic to try and properly layer its elements on the fly, and that is why you see it work fine in the example. This was necessary because incorrectly layered polygons are very obvious.

Looking over the code for Line3DCollection, it does not have any of this sophistication. I am presuming that it is because incorrectly layered lines are not nearly as visually obvious compared to polygons. I didn't even realize that one can make something like a polygon collection out of a line collection! @mdboom , Is that even a supported feature of LineCollections, or is that an accident of design?

If that is a supported feature of LineCollections, then I will see if I can utilize the same code in Poly3DCollection in Line3DCollection, which should fix this problem.

@demisjohn
Copy link
Author

Thanks for your rapid reply.
Supported or not, the LineCollection3D is a fantastic visualization tool, that I've used in a few publications already, and have passed on to researchers in other fields for visualizing their own complex data.
Your work on this is greatly appreciated!

Are there any tests you'd like me to try to help you out?

@petehuang
Copy link
Contributor

Confirming this still exists in 1.5.3.

@WeatherGod did you end up getting any guidance from @mdboom?

@demisjohn
Copy link
Author

Has there been any progress on this?
FYI I should point out that LineCollection allows you to plot arbitrary Data (that's what we use it for), while PolygonColection isn't really intended for that.

We use it in our research papers, for example see Fig 2 in this paper:
http://praevium.com/wptest_v1/wp-content/uploads/2015/08/2015-JLT-JohnJayaraman-Wideband-Electrically-Pumped-1050-nm-MEMS-Tunable-VCSEL-for-Ophthalmic-Imaging.pdf

@github-actions
Copy link

github-actions bot commented Oct 9, 2023

This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label Oct 9, 2023
@github-actions github-actions bot added the status: closed as inactive Issues closed by the "Stale" Github Action. Please comment on any you think should still be open. label Nov 8, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Nov 8, 2023
@demisjohn
Copy link
Author

demisjohn commented Nov 14, 2023

Checking this - bug is still present, in Anaconda / Python 3.11, Spyder 5.4.3, matplotlib 3.7.1

Screenshot 2023-11-13 201925

(Unrelated) - the demo script now produces an error near the start;
demo script in docs page:

fig = plt.figure()
ax = fig.gca(projection='3d')

Result (python 3.11):
TypeError: FigureBase.gca() got an unexpected keyword argument 'projection'

Had to replace line with ax = fig.add_subplot(projection='3d') as per this hint.


Here is the modified demo script to reproduce this problem:


"""
=============================================
Generate polygons to fill under 3D line graph
=============================================

Demonstrate how to create polygons which fill the space under a line
graph. In this example polygons are semi-transparent, creating a sort
of 'jagged stained glass' effect.
"""

from mpl_toolkits.mplot3d import Axes3D
from matplotlib.collections import PolyCollection, LineCollection
import matplotlib.pyplot as plt
from matplotlib import colors as mcolors
import numpy as np


fig = plt.figure()
ax = fig.add_subplot(projection='3d')

#ax = fig.gca(projection='3d')
#fig, ax = plt.subplots(projection='3d')

def cc(arg):
    return mcolors.to_rgba(arg, alpha=1.0)

xs = np.arange(0, 10, 0.4)
verts = []
zs = [0.0, 1.0, 2.0, 3.0]
for z in zs:
    ys = np.random.rand(len(xs))
    ys[0], ys[-1] = 0, 0
    verts.append(list(zip(xs, ys)))

#poly = PolyCollection(verts, facecolors=[cc('r'), cc('g'), cc('b'), cc('y')])
poly = LineCollection(verts, facecolors=[cc('r'), cc('g'), cc('b'), cc('y')])
    
poly.set_alpha(1.0)
ax.add_collection3d(poly, zs=zs, zdir='y')

ax.set_xlabel('X')
ax.set_xlim3d(0, 10)
ax.set_ylabel('Y')
ax.set_ylim3d(-1, 4)
ax.set_zlabel('Z')
ax.set_zlim3d(0, 1)

plt.show()

@oscargus oscargus reopened this Nov 14, 2023
@oscargus oscargus added keep Items to be ignored by the “Stale” Github Action and removed status: inactive Marked by the “Stale” Github Action status: closed as inactive Issues closed by the "Stale" Github Action. Please comment on any you think should still be open. labels Nov 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
keep Items to be ignored by the “Stale” Github Action topic: mplot3d
Projects
None yet
Development

No branches or pull requests

6 participants