使用python和matplotlib,在两行之间填充不给出预期输出

时间:2017-01-30 11:46:34

标签: python matplotlib

我正在尝试绘制一条带有相关错误的线性线。 我计算了斜率(a)和截距(b)的值。另外,我计算了与这些值相关的误差。所以我画了下面典型公式给出的线。

  

Y = AX + B

但是,除了该行之外,我还想绘制相关的错误。我想出了绘制与这些公式相关的线条并为灰色线条之间的空间着色的想法。

  

Y =(A + a_sd)X +(B + b_sd)

     

y =(a-a_sd)x +(b-b_sd)

使用下面的代码,我能够对线条之间的部分表面进行着色,而不是整个跨度(参见包含的输出)。
我认为这可能是因为“距离”没有排序,而fill_between分别使用距离[0]和距离[-1]作为跨度的开始和结束。
一如既往,任何帮助都将受到高度赞赏!

import matplotlib.pyplot as plt

distance=[0.35645334340084989, 0.55406894241607718, 0.10201413273193734, 0.13401365724625941, 0.71918808865838735, 0.14151335417722818]
time=[2.4004984846346171, 2.4909766335028447, 1.9852064018125195, 1.9083156734132103, 2.6380396934372863, 1.9114505780323543]
time_SD=[0.062393810960652669, 0.056945715242838917, 0.073960838867327183, 0.084111239062664475, 0.026912957190265499, 0.08595664694840538]
distance_SD=[0.035160608598240162, 0.032976715460514235, 0.02782911002465227, 0.035465701695038584, 0.043009444687382707, 0.038387585107200854]
a=1.17887019041
b=1.83339229489
a_sd=0.159771527859
b_sd=0.0762509747218

plt.errorbar(distance,time,yerr=time_SD, xerr=distance_SD, linestyle="None") 
abline_values = [(a)*i + (b) for i in distance]
abline_values_plus = [(a+a_sd)*i + (b+b_sd) for i in distance]
abline_values_minus = [(a-a_sd)*i + (b-b_sd) for i in distance]
plt.plot(distance, abline_values,"r")
plt.fill_between(distance,abline_values_minus,abline_values_plus,facecolor='lightgrey', interpolate=True, edgecolors="None")
leg = plt.legend(loc="lower right", frameon=False, handlelength=0, handletextpad=0)
for item in leg.legendHandles:
    item.set_visible(False)
plt.show()

enter image description here

2 个答案:

答案 0 :(得分:2)

为了使用pyplot.fill_between() 列表,应该对水平坐标进行排序。可以使用未排序的x值列表,但可能导致不希望的结果。

可以使用sorted(list)对列表进行排序。

import matplotlib.pyplot as plt

distance=[0.35645334340084989, 0.55406894241607718, 0.10201413273193734, 0.13401365724625941, 0.71918808865838735, 0.14151335417722818]
time=[2.4004984846346171, 2.4909766335028447, 1.9852064018125195, 1.9083156734132103, 2.6380396934372863, 1.9114505780323543]
time_SD=[0.062393810960652669, 0.056945715242838917, 0.073960838867327183, 0.084111239062664475, 0.026912957190265499, 0.08595664694840538]
distance_SD=[0.035160608598240162, 0.032976715460514235, 0.02782911002465227, 0.035465701695038584, 0.043009444687382707, 0.038387585107200854]
a=1.17887019041
b=1.83339229489
a_sd=0.159771527859
b_sd=0.0762509747218

distance_sorted = sorted(distance)

plt.errorbar(distance,time,yerr=time_SD, xerr=distance_SD, linestyle="None") 
abline_values = [(a)*i + (b) for i in distance_sorted]
abline_values_plus = [(a+a_sd)*i + (b+b_sd) for i in distance_sorted]
abline_values_minus = [(a-a_sd)*i + (b-b_sd) for i in distance_sorted]
plt.plot(distance_sorted, abline_values,"r")

plt.fill_between(distance_sorted,abline_values_minus,abline_values_plus, facecolor='lightgrey', edgecolors="None")

plt.show()

<小时/> 文档没有提到要对x值进行排序的要求。原因可能是fill_between实际上甚至可以用于未排序的列表,而不是人们可能期望的方式。也许下面的动画可以更直观地理解这个问题:

enter image description here

答案 1 :(得分:1)

你是对的fill_between似乎期望对值进行排序。 documentation 虽然不清楚这种行为。但是,以下示例显示了相同的效果:

import matplotlib.pyplot as plt
from numpy import random, array

#x = random.randn(20) #does not work
x = array(sorted(random.randn(20))) #works

a = 2
d = .5

y_h = x*(a+d)
y_l = x*(a-d)

plt.fill_between(x,y_h, y_l)
plt.show()

作为一种解决方法,只需在使用sorted计算错误行之前对值进行排序。