You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have come across an odd layering issue with errorbars. The errorbar caps are not drawn at the same layer as the errorbar itself. Also, the line connecting multiple errorbars are plotted on a completely different layer than the errorbars. I am attaching an example demonstrating this. Note the green caps are showing up on top of the red errorbar, meanwhile, the red errorbar is drawn on top of the green errorbar. Also notice that the thin red line connecting the red errorbars is showing up on top of the green cap for lambda = 1.
I am not exactly sure how this should be fixed. It is most likely an issue with the fact that the caps are drawn as markers instead of a line (I am guessing so that the marker would then be sized based on width in points instead of data). When an axes' child objects are z-sorted, the objects that do not declare a z-order are loaded in the order of their creation (or is it in some arbitrary order based on the type of collection?).
Does anyone know a workaround? I plot a lot of lines and afterwards I want to plot the error bars on top of them. This works for the upper and lower horizontal lines, but the vertical line is in the back.
Is there a way of getting those line elements and changing their layer so that they appear on top of the rest?
Thanks for the nudge. No, it isn't fixed. I modified one of the example scripts to demonstrate the issue.
The linewidths and cap sizes are exaggerated in order to make the problem very visible.
from math import pi
from numpy import array, arange, sin
import pylab as P
fig = P.figure()
x = arange(10.0)
y = sin(arange(10.0)/20.0*pi)
P.errorbar(x,y,yerr=0.5,capsize=10,linewidth=5)
y = sin(arange(10.0)/20.0*pi) + 0.5
P.errorbar(x,y,yerr=0.5, uplims=True, capsize=10, linewidth=5)
y = sin(arange(10.0)/20.0*pi) + 0.75
upperlimits = array([1,0]*5)
lowerlimits = array([0,1]*5)
P.errorbar(x, y, yerr=0.5, uplims=upperlimits, lolims=lowerlimits, capsize=10, linewidth=5)
P.xlim(-1,10)
P.show()
The default zorder of lines and collections are still different (I think lines are 0, collections are 1 and line collections are 2). If you add explicit zorder arguments to this example it behaves properly.
The answer may be that errorbar should have a finite default value of zorder instead of leaving it as None
from math import pi
from numpy import array, arange, sin
import pylab as P
fig = P.figure()
x = arange(10.0)
y = sin(arange(10.0)/20.0*pi)
P.errorbar(x,y,yerr=0.5,capsize=10,linewidth=5, zorder=0)
y = sin(arange(10.0)/20.0*pi) + 0.5
P.errorbar(x,y,yerr=0.5, uplims=True, capsize=10, linewidth=5, zorder=1)
y = sin(arange(10.0)/20.0*pi) + 0.75
upperlimits = array([1,0]*5)
lowerlimits = array([0,1]*5)
P.errorbar(x, y, yerr=0.5, uplims=upperlimits, lolims=lowerlimits, capsize=10, linewidth=5, zorder=2)
P.xlim(-1,10)
P.show()
This is actually a deeper issue than I first grasped.
Because errorbar is drawn using a set of artists (Line2D and Collection objects) which get added to different lists inside the Axes object. The vertical lines are drawn using vlines which returns a LineCollection and the caps are drawn using plot which returns a Line2D object. In Axes.draw all of the artists are collected into a single list (collections first, then lines) and sorted by zorder, for a set of errorbar plots with the same zorder all of the caps will always be drawn after all of the bars are drawn.
Short of re-writing how draw works or a major re-write of errorbar, this is not fixable.
This is another case where having sematic high-level containers (see thread on mailing list about the D3 work) would be helpful.
I agree that it would be hard to fix this problem. This is yet another reason for updating our rendering engine to utilize a DOM tree traversal rather than this layering approach.
Activity
a6073758 commentedon Oct 23, 2012
Does anyone know a workaround? I plot a lot of lines and afterwards I want to plot the error bars on top of them. This works for the upper and lower horizontal lines, but the vertical line is in the back.
Is there a way of getting those line elements and changing their layer so that they appear on top of the rest?
a6073758 commentedon Oct 23, 2012
Ok, I found the solution already. I plot all those lines which should appear in the background with the keyword zorder=1. That one did the trick.
tacaswell commentedon Jan 26, 2013
@WeatherGod Is this fixed? Sorry to pester you.
pelson commentedon Feb 15, 2013
Nudge.
WeatherGod commentedon Feb 15, 2013
Thanks for the nudge. No, it isn't fixed. I modified one of the example scripts to demonstrate the issue.

The linewidths and cap sizes are exaggerated in order to make the problem very visible.
tacaswell commentedon Feb 15, 2013
The default zorder of lines and collections are still different (I think lines are 0, collections are 1 and line collections are 2). If you add explicit zorder arguments to this example it behaves properly.
The answer may be that
errorbarshould have a finite default value ofzorderinstead of leaving it asNonetacaswell commentedon Jan 16, 2014
note to self: set a default zorder for error bars
tacaswell commentedon Jan 17, 2014
This is actually a deeper issue than I first grasped.
Because
errorbaris drawn using a set of artists (Line2DandCollectionobjects) which get added to different lists inside theAxesobject. The vertical lines are drawn usingvlineswhich returns aLineCollectionand the caps are drawn usingplotwhich returns aLine2Dobject. InAxes.drawall of the artists are collected into a single list (collections first, then lines) and sorted by zorder, for a set oferrorbarplots with the same zorder all of the caps will always be drawn after all of the bars are drawn.Short of re-writing how
drawworks or a major re-write oferrorbar, this is not fixable.This is another case where having sematic high-level containers (see thread on mailing list about the D3 work) would be helpful.
tacaswell commentedon Feb 1, 2014
Removed the milestone and flagged and taagging as wontfix. To get the ordering correct, you need to explicitly set the z-order of each
errorbarcall.@WeatherGod If you agree, please close.
WeatherGod commentedon Feb 3, 2014
I agree that it would be hard to fix this problem. This is yet another reason for updating our rendering engine to utilize a DOM tree traversal rather than this layering approach.
Maybe we should have a new tag "cantfix"?
tacaswell commentedon Feb 3, 2014
done