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 commented on 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 commented on 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 commented on Jan 26, 2013
@WeatherGod Is this fixed? Sorry to pester you.
pelson commented on Feb 15, 2013
Nudge.
WeatherGod commented on 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 commented on 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 errorbar should have a finite default value of zorder instead of leaving it as None
tacaswell commented on Jan 16, 2014
note to self: set a default zorder for error bars
tacaswell commented on Jan 17, 2014
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.
tacaswell commented on 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 errorbar call.
@WeatherGod If you agree, please close.
WeatherGod commented on 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 commented on Feb 3, 2014
done