Issue
I encountered a rather strange behavior of legend and the errorbar plot commands. I am using Python xy 2.7.3.1 with matplotlib 1.1.1
The code below exemplifies the observed behavior:
import pylab as P
import numpy as N
x1=N.linspace(0,6,10)
y1=N.sin(x1)
x2=N.linspace(0,6,5000)
y2=N.sin(x2)
xerr = N.repeat(0.01,10)
yerr = N.repeat(0.01,10)
#error bar caps visible in scatter dots
P.figure()
P.subplot(121)
P.title("strange error bar caps")
P.scatter(x1,y1,s=100,c="k",zorder=1)
P.errorbar(x1,y1,yerr=yerr,xerr=xerr,color="0.7",
ecolor="0.7",fmt=None, zorder=0)
P.plot(x2,y2,label="a label")
P.legend(loc="center")
P.subplot(122)
P.title("strange legend behaviour")
P.scatter(x1,y1,s=100,c="k",zorder=100)
P.errorbar(x1,y1,yerr=yerr,xerr=xerr,color="0.7",
ecolor="0.7",fmt=None, zorder=99)
P.plot(x2,y2,label="a label", zorder=101)
P.legend(loc="center")
P.show()
which yields this plot:
As you can see, the errorbar caps are overwriting the scatter plot. If I increase zorder enough this does not happen any more, but the plot line overwrites the legend. I have the suspicion that the problem is related to this zorder problem with matplotlib.
Quick, dirty, hacky solutions also appreciated.
Edit (thanks @nordev): the desired outcome is the following:
- errorbars, as well as the ending caps shall be below the scatter plot point.
- the line plot shall be above the scatter and the error bars
- the legend shall be above all others
Adjusting the zorder according to your answer:
P.legend(zorder=100)
-->self.legend_ = mlegend.Legend(self, handles, labels, **kwargs) TypeError: __init__() got an unexpected keyword argument 'zorder'
P.errorbar(zorder=0)
,P.scatter(zorder=1)
, ... as correctly suggested by you, still yields the same plot, the error bar caps are still above the scatter dots. I corrected the example above accordingly.
Solution
The created plots are correct according to the code you have posted. The objects with the lowest zorder
is placed on the bottom, while the object with the highest zorder
is placed on top. The zorder problem you linked to is fixed in matplotlib version 1.2.1, so you should update your install if possible.
In your first subplot the errorbars are plotted on top of the scatter points because errorbar
is called with zorder=2
, while scatter
is called with zorder=1
- meaning the errorbars will overlay the scatter points.
In your second subplot, you have called errorbar
with zorder=99
, scatter
with zorder=100
and plot
with zorder=101
- meaning that the errorbars will be placed underneath both the scatter points and the line.
The reason the legend
is displayed on top of the line in the first subplot, while it is on top of the same line in the second subplot, is due to the fact that you haven't explicitly set the legend objecta zorder
value, meaning it will use its default value (which I believe is 5). To change the legends zorder, simply use P.legend(loc="center").set_zorder(102)
where 102 is the desired zorder-value.
So in order to produce your desired output, you have to set the zorder
arguments accordingly. As you haven't described your desired output in your question, it is hard for me to "correct" your code, as I don't know in which order you want the objects to be drawn.
Answered By - sodd
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.