Skip to content
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

axis('equal') in mplot3d plots causes duplicate z axis in the nbagg backend #4971

Closed
jenshnielsen opened this issue Aug 20, 2015 · 11 comments
Closed
Assignees
Milestone

Comments

@jenshnielsen
Copy link
Member

This is on current master I can't reproduce this using 1.4.3. I guess it relates to the stale auto redraw handling?

from mpl_toolkits.mplot3d import Axes3D


fig = plt.figure(figsize=(6.5,5.5))
ax = fig.add_subplot(1, 1, 1, projection='3d')
xs = np.random.rand(10)
ys = np.random.rand(10)
zs = np.random.rand(10)
ax.set_aspect('equal')

ax.scatter(xs, ys, zs)
ax.set_xlim(0,1)
ax.set_ylim(0,1)
ax.set_zlim(0,1)
fig.tight_layout()

results in

download 2

Rotating the figure restores the correct axes. I can't reproduce it with QT5Agg or GTK3Agg

It seems like both the equal axis z and the original z axis are drawn on top of each other. It doesn't seem to happen in regular 2D plots.

@jenshnielsen jenshnielsen added this to the next point release milestone Aug 20, 2015
@tacaswell
Copy link
Member

What backends does this happen on?

@jenshnielsen
Copy link
Member Author

nbagg (Bug title ;)

I can't reproduce it with any of the GUI Backends that I have tried.

@tacaswell
Copy link
Member

Ha! Sorry I can't read.

nbagg has two canvas instances that it swaps between (so that in can compute the diffs). I bet there is something sutble going on with draw order/it's draw_idle not being good enough at snarfing duplicate draws.

I am thinking of putting the non-propagation of stale state past an already stale artist back in. Always propagating prevents a corner case annoyance in vanilla python repl where an error in drawing prevents auto-draw from working on that figure until it is manually kicked (via plt.draw_all() or fig.canvas.draw() or plt.draw() if it is the active figure) but is introducing all sorts of re-entrant issues with backends that don't fully implement draw_idle correctly.

attn @mdehoon

@mdehoon
Copy link
Contributor

mdehoon commented Aug 21, 2015

@tacaswell Which backend does not implement draw_idle correctly?

@mdehoon
Copy link
Contributor

mdehoon commented Aug 21, 2015

I am seeing this bug also with the MacOSX backend and the tkagg backend; I haven't tried the other backends.

@tacaswell
Copy link
Member

Having issues with Qt, but I think those are sorted. I am not sure about nbagg.

@WeatherGod
Copy link
Member

Just curious... what is special about mplot3d that would trigger this
problem? mplot3d doesn't mess around with draw/draw_idle, and it doesn't do
blitting or anything of that sort. The only thing I can think of is that it
performs a lot of extra computation at each artist draw(), but that's all.

On Fri, Aug 21, 2015 at 9:27 AM, Thomas A Caswell notifications@github.com
wrote:

Having issues with Qt, but I think those are sorted. I am not sure about
nbagg.


Reply to this email directly or view it on GitHub
#4971 (comment)
.

@jenshnielsen
Copy link
Member Author

It's totally possible that this can be triggered without mplot3d. That's just where I happened to spot it. I can't reproduce it with a regular scatter plot but there might be some other way.

@mdehoon
Copy link
Contributor

mdehoon commented Aug 22, 2015

@tacaswell OK. If you notice any other implementation problems with draw_idle in any of the backends, I'd be happy to have a look.

@tacaswell
Copy link
Member

The issue seems to be that the z-axis is in the draw tree twice, once before things get updated and once after. It look mostly ok most of the time because they are getting over-drawn on top of each other.

@WeatherGod
Copy link
Member

A possible clue on that... the ZAxis is basically implemented as a XAxis
subclass rather than creating a whole new class like YAxis. There are
several spots in the codebase where the z-axis basically "steals" from the
x-axis, but I really don't know how it would end up putting itself into the
draw-tree twice.

On Sat, Aug 22, 2015 at 4:52 PM, Thomas A Caswell notifications@github.com
wrote:

The issue seems to be that the z-axis is in the draw tree twice, once
before things get updated and once after. It look mostly ok most of the
time because they are getting over-drawn on top of each other.


Reply to this email directly or view it on GitHub
#4971 (comment)
.

tacaswell added a commit to tacaswell/matplotlib that referenced this issue Aug 26, 2015
When we moved `Axes.draw` to use `Axes.get_children` to get the initial
list of artists to draw the zaxis was now in this list (where as it was
not previously).  The 3D axes use `_axison = False` as `Axes3D` manages
the drawing of the axis objects (which must happen before any of the
artists). In `Axes.draw` there is a special case to remove the x and y
axis from the draw list if `not _axison`.

This change is to add a `_get_axis_list` method to the `Axes` base class
and override this in the `Axes3D`.  This list is looped over to remove
all of the `axis` objects that when the axises should not be shown.

Closes matplotlib#4971
@tacaswell tacaswell self-assigned this Aug 26, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants