问题描述
我遇到了一个相当奇怪的图例行为和 errorbar plot 命令.我在 matplotlib 1.1.1
中使用Python xy 2.7.3.1下面的代码举例说明了观察到的行为:
将pylab导入为P将 numpy 导入为 Nx1=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)#在分散点中可见的错误栏上限P.figure()子图(121)P.title("奇怪的错误栏帽")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")子图(122)P.title(奇怪的传奇行为")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()
产生这个图:
如您所见,误差条上限覆盖了散点图.如果我增加zorder足够多,这种情况将不再发生,但情节线将覆盖图例.我怀疑这个问题与这个zorder问题有关 与 matplotlib.
快速、肮脏、笨拙的解决方案也很受欢迎.
编辑(感谢@nordev):预期结果如下:
- 误差线和结尾处的值应位于散点图的下方.
- 线图应位于散点图和误差线上方
- 传奇高于一切
根据您的答案调整zorder:
-
P.legend(zorder = 100)
->self.legend_ = mlegend.Legend(自身,句柄,标签,**变格)类型错误:__init__() 得到了一个意外的关键字参数 'zorder'
P.errorbar(zorder=0)
,P.scatter(zorder=1)
, ...正如您所正确建议的,仍然产生相同的图,误差条的上限仍在散点上方.我相应地更正了上面的示例.
根据您发布的代码,创建的图是正确的.最低 zorder
的对象放在底部,而最高 zorder
的对象放在最佳.您链接到的 zorder 问题已在 matplotlib 版本 1.2.1 中修复,因此您应该尽可能更新您的安装.
在您的第一个子图中,错误栏绘制在散点上方,因为使用 zorder = 2
调用 errorbar
,而 scatter
用 zorder = 1
调用-意味着错误栏将覆盖分散点.
在第二个子图中,您使用 zorder=99
调用了 errorbar
,使用 zorder=100
调用了 scatter
和 plot
和 zorder = 101
-意味着误差线将被放置在散点和线的下方.
legend
在第一个子图中显示在行的顶部,而在第二个子图中显示在同一行的顶部的原因是因为您没有显式设置图例对象 zorder
值,这意味着它将使用其默认值(我认为是 5).要更改图例的zorder,只需使用 P.legend(loc ="center").set_zorder(102)
,其中102是所需的zorder值.
因此,为了产生您想要的输出,您必须相应地设置 zorder
参数.由于您尚未在问题中描述您的所需输出,因此我很难更正"您的代码,因为我不知道您希望按什么顺序绘制对象./p>
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.
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.
这篇关于带有图例和错误栏的奇怪 matplotlib zorder 行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!