Skip to content

Errorbar layering #409

Closed
Closed

Description

@WeatherGod

This was first reported on the mailing list by me here: http://old.nabble.com/errorbar-layering-issue--td32149181.html
An image depicting the problem is also available through that link. The message text is below.

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?).

Activity

  1. a6073758 commented on Oct 23, 2012

    @a6073758

    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?

  2. a6073758 commented on Oct 23, 2012

    @a6073758

    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.

  3. tacaswell commented on Jan 26, 2013

    @tacaswell
    Member

    @WeatherGod Is this fixed? Sorry to pester you.

  4. pelson commented on Feb 15, 2013

    @pelson
    Member

    Nudge.

  5. WeatherGod commented on Feb 15, 2013

    @WeatherGod
    MemberAuthor

    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.
    errorbar_layering

    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()
    
  6. tacaswell commented on Feb 15, 2013

    @tacaswell
    Member

    with_zorder
    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()
    
  7. tacaswell commented on Jan 16, 2014

    @tacaswell
    Member

    note to self: set a default zorder for error bars

  8. tacaswell commented on Jan 17, 2014

    @tacaswell
    Member

    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.

  9. tacaswell commented on Feb 1, 2014

    @tacaswell
    Member

    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.

  10. WeatherGod commented on Feb 3, 2014

    @WeatherGod
    MemberAuthor

    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"?

  11. tacaswell commented on Feb 3, 2014

    @tacaswell
    Member

    done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions