用 matplotlib 填充行与行之间的 space
Filling in the space between lines with matplotlib
我正在编写一个 python 程序,该程序将 .csv 文件中的数据绘制为财务价值与格式为月-日-年的日期。一条线代表财务价值的较高估计值,另一条线代表较低的估计值,第三条线代表平均估计值。我试图让绘图用红色填充上限和下限估计之间的区域,并覆盖代表平均值的黑线。我可以将每个数据集绘制成一条线,但出于某种原因,它不允许我用红色填充上限和下限之间的 space。下图显示了几何形状,我试图在红线之间填充 space。当我 运行 使用 fill_between 命令的代码时,我收到消息“condition = ~(np.isfinite(a))。任何人都可以发现我的问题所在。我增加了一个月的价值.csv 文件和整个代码中的数据点,以更好地理解机制,或缺乏这些。
#!/usr/bin/python
import csv
import sys
import datetime
from pylab import *
from matplotlib.ticker import MaxNLocator
date = []
Median = []
Upper = []
Lower = []
inp = open('Checking.csv','rt')
try:
reader = csv.reader(inp)
for row in reader:
Init_Date = row[0]
if(Init_Date[0:3] == 'Jan'): Month = 1
elif(Init_Date[0:3] == 'Feb'): Month = 2
elif(Init_Date[0:3] == 'Mar'): Month = 3
elif(Init_Date[0:3] == 'Apr'): Month = 4
elif(Init_Date[0:3] == 'May'): Month = 5
elif(Init_Date[0:3] == 'Jun'): Month = 6
elif(Init_Date[0:3] == 'Jul'): Month = 7
elif(Init_Date[0:3] == 'Aug'): Month = 8
elif(Init_Date[0:3] == 'Sep'): Month = 9
elif(Init_Date[0:3] == 'Oct'): Month = 10
elif(Init_Date[0:3] == 'Nov'): Month = 11
else: Month = 12
day = Init_Date[4:6]
year = Init_Date[-3:-1]
Median.append(row[1])
Upper.append(row[2])
Lower.append(row[3])
dates = str(Month) + '/' + str(day).strip() + '/' + str(year)
date.append(datetime.datetime.strptime(dates,'%m/%d/%y'))
finally:
inp.close()
fig, plt = plt.subplots()
matplotlib.rc('xtick',labelsize=18)
matplotlib.rc('ytick',labelsize=18)
x = date
y = Median
y1 = Upper
y2 = Lower
plt.set_xlabel(r'$Date$',fontsize = 18)
plt.set_ylabel(r'$Y-Value$',fontsize = 18)
plt.plot(x, y1, color = 'red')
plt.plot(x, y2, color = 'red')
plt.fill_between(x,y2,y1,interpolate=True,color='red')
plt.plot(x, y, color = 'black')
plt.xaxis.set_major_locator(MaxNLocator(nbins = 12))
fig.savefig("Test.png")
测试数据
Mar 2 2014 18339.1 18734.15 17944.05
Mar 3 2014 18280.33 18675.39 17885.26
Mar 4 2014 18220.61 18614.84 17826.39
Mar 5 2014 18160.77 18552.15 17769.39
Mar 6 2014 18100.92 18493.55 17708.28
Mar 7 2014 18042.18 18431.77 17652.59
Mar 8 2014 17983.51 18371.31 17595.71
Mar 9 2014 17577.67 17959.34 17196
Mar 10 2014 17517.87 17898.33 17137.42
Mar 11 2014 15956.97 16309.96 15603.98
Mar 12 2014 15403.36 15746.7 15060.03
Mar 13 2014 15344.04 15684.44 15003.65
Mar 14 2014 20731.34 21171.47 20291.2
Mar 15 2014 22986.67 23469.15 22504.18
Mar 16 2014 22926.7 23408.98 22444.42
Mar 17 2014 22867.46 23348.73 22386.19
Mar 18 2014 22541.08 23015.78 22066.39
Mar 19 2014 22481.86 22955.47 22008.25
Mar 20 2014 22420.94 22895.56 21946.32
Mar 21 2014 22361.48 22832.68 21890.28
Mar 22 2014 22301.09 22771.64 21830.53
Mar 23 2014 21972.47 22435.43 21509.52
Mar 24 2014 21913.41 22376.04 21450.77
Mar 25 2014 21251.91 21701.94 20801.88
Mar 26 2014 21192.85 21642.57 20743.12
Mar 27 2014 21133.16 21582 20684.31
Mar 28 2014 21074.7 21521.39 20628.01
Mar 29 2014 21014.04 21461.03 20567.05
Mar 30 2014 24122.28 24627.21 23617.35
Mar 31 2014 24063.07 24566.59 23559.55
不知是否与您的数据有关。 fill_between 可能无法处理复杂的数据。你的代码适用于不同的数据(我稍微修剪了一下):
x = [1,2,3,4]
y1 = [1,2,3,4]
y2 = [2,3,4,5]
y = [1.5,2.5,3.5,4.5]
plt.plot(x, y1, color = 'red')
plt.plot(x, y2, color = 'red')
plt.fill_between(x,y2,y1,interpolate=True,color='red')
plt.plot(x, y, color = 'black')
plt.show()
结果符合预期。不错的把戏。我从未见过 fill_between。不要放弃希望。我确定有人有解决方法。
编辑:
用我的简单数据尝试你所有的代码也行。我不明白为什么它不适合你,但除了坏数据之外,一些要检查的事情可能是 matplotlib 是否是最新的以及你的后端设置是否正确。
错误是由于传递给 fill_between
的数据属于 string
类型造成的。如果您 print
y
、y1
和 y2
变量就在绘图之前,您可以看到问题:
>>> print(y)
['18339.1', '18280.33', '18220.61', '18160.77', '18100.92', '18042.18', '17983.51', '17577.67', '17517.87', '15956.97', '15403.36', '15344.04', '20731.34', '22986.67', '22926.7', '22867.46', '22541.08', '22481.86', '22420.94', '22361.48', '22301.09', '21972.47', '21913.41', '21251.91', '21192.85', '21133.16', '21074.7', '21014.04', '24122.28', '24063.07']
>>> print(y1)
['18734.15', '18675.39', '18614.84', '18552.15', '18493.55', '18431.77', '18371.31', '17959.34', '17898.33', '16309.96', '15746.7', '15684.44', '21171.47', '23469.15', '23408.98', '23348.73', '23015.78', '22955.47', '22895.56', '22832.68', '22771.64', '22435.43', '22376.04', '21701.94', '21642.57', '21582', '21521.39', '21461.03', '24627.21', '24566.59']
>>> print(y2)
['17944.05', '17885.26', '17826.39', '17769.39', '17708.28', '17652.59', '17595.71', '17196', '17137.42', '15603.98', '15060.03', '15003.65', '20291.2', '22504.18', '22444.42', '22386.19', '22066.39', '22008.25', '21946.32', '21890.28', '21830.53', '21509.52', '21450.77', '20801.88', '20743.12', '20684.31', '20628.01', '20567.05', '23617.35', '23559.55']
解决方案是在绘图之前将它们转换为数字类型(例如float
)。最简单的地方是您构建列表的地方:
Median.append( float(row[1]) )
Upper.append( float(row[2]) )
Lower.append( float(row[3]) )
现在 fill_between
将按预期工作,您的脚本将产生以下情节:
我正在编写一个 python 程序,该程序将 .csv 文件中的数据绘制为财务价值与格式为月-日-年的日期。一条线代表财务价值的较高估计值,另一条线代表较低的估计值,第三条线代表平均估计值。我试图让绘图用红色填充上限和下限估计之间的区域,并覆盖代表平均值的黑线。我可以将每个数据集绘制成一条线,但出于某种原因,它不允许我用红色填充上限和下限之间的 space。下图显示了几何形状,我试图在红线之间填充 space。当我 运行 使用 fill_between 命令的代码时,我收到消息“condition = ~(np.isfinite(a))。任何人都可以发现我的问题所在。我增加了一个月的价值.csv 文件和整个代码中的数据点,以更好地理解机制,或缺乏这些。
#!/usr/bin/python
import csv
import sys
import datetime
from pylab import *
from matplotlib.ticker import MaxNLocator
date = []
Median = []
Upper = []
Lower = []
inp = open('Checking.csv','rt')
try:
reader = csv.reader(inp)
for row in reader:
Init_Date = row[0]
if(Init_Date[0:3] == 'Jan'): Month = 1
elif(Init_Date[0:3] == 'Feb'): Month = 2
elif(Init_Date[0:3] == 'Mar'): Month = 3
elif(Init_Date[0:3] == 'Apr'): Month = 4
elif(Init_Date[0:3] == 'May'): Month = 5
elif(Init_Date[0:3] == 'Jun'): Month = 6
elif(Init_Date[0:3] == 'Jul'): Month = 7
elif(Init_Date[0:3] == 'Aug'): Month = 8
elif(Init_Date[0:3] == 'Sep'): Month = 9
elif(Init_Date[0:3] == 'Oct'): Month = 10
elif(Init_Date[0:3] == 'Nov'): Month = 11
else: Month = 12
day = Init_Date[4:6]
year = Init_Date[-3:-1]
Median.append(row[1])
Upper.append(row[2])
Lower.append(row[3])
dates = str(Month) + '/' + str(day).strip() + '/' + str(year)
date.append(datetime.datetime.strptime(dates,'%m/%d/%y'))
finally:
inp.close()
fig, plt = plt.subplots()
matplotlib.rc('xtick',labelsize=18)
matplotlib.rc('ytick',labelsize=18)
x = date
y = Median
y1 = Upper
y2 = Lower
plt.set_xlabel(r'$Date$',fontsize = 18)
plt.set_ylabel(r'$Y-Value$',fontsize = 18)
plt.plot(x, y1, color = 'red')
plt.plot(x, y2, color = 'red')
plt.fill_between(x,y2,y1,interpolate=True,color='red')
plt.plot(x, y, color = 'black')
plt.xaxis.set_major_locator(MaxNLocator(nbins = 12))
fig.savefig("Test.png")
测试数据
Mar 2 2014 18339.1 18734.15 17944.05
Mar 3 2014 18280.33 18675.39 17885.26
Mar 4 2014 18220.61 18614.84 17826.39
Mar 5 2014 18160.77 18552.15 17769.39
Mar 6 2014 18100.92 18493.55 17708.28
Mar 7 2014 18042.18 18431.77 17652.59
Mar 8 2014 17983.51 18371.31 17595.71
Mar 9 2014 17577.67 17959.34 17196
Mar 10 2014 17517.87 17898.33 17137.42
Mar 11 2014 15956.97 16309.96 15603.98
Mar 12 2014 15403.36 15746.7 15060.03
Mar 13 2014 15344.04 15684.44 15003.65
Mar 14 2014 20731.34 21171.47 20291.2
Mar 15 2014 22986.67 23469.15 22504.18
Mar 16 2014 22926.7 23408.98 22444.42
Mar 17 2014 22867.46 23348.73 22386.19
Mar 18 2014 22541.08 23015.78 22066.39
Mar 19 2014 22481.86 22955.47 22008.25
Mar 20 2014 22420.94 22895.56 21946.32
Mar 21 2014 22361.48 22832.68 21890.28
Mar 22 2014 22301.09 22771.64 21830.53
Mar 23 2014 21972.47 22435.43 21509.52
Mar 24 2014 21913.41 22376.04 21450.77
Mar 25 2014 21251.91 21701.94 20801.88
Mar 26 2014 21192.85 21642.57 20743.12
Mar 27 2014 21133.16 21582 20684.31
Mar 28 2014 21074.7 21521.39 20628.01
Mar 29 2014 21014.04 21461.03 20567.05
Mar 30 2014 24122.28 24627.21 23617.35
Mar 31 2014 24063.07 24566.59 23559.55
不知是否与您的数据有关。 fill_between 可能无法处理复杂的数据。你的代码适用于不同的数据(我稍微修剪了一下):
x = [1,2,3,4]
y1 = [1,2,3,4]
y2 = [2,3,4,5]
y = [1.5,2.5,3.5,4.5]
plt.plot(x, y1, color = 'red')
plt.plot(x, y2, color = 'red')
plt.fill_between(x,y2,y1,interpolate=True,color='red')
plt.plot(x, y, color = 'black')
plt.show()
结果符合预期。不错的把戏。我从未见过 fill_between。不要放弃希望。我确定有人有解决方法。
编辑:
用我的简单数据尝试你所有的代码也行。我不明白为什么它不适合你,但除了坏数据之外,一些要检查的事情可能是 matplotlib 是否是最新的以及你的后端设置是否正确。
错误是由于传递给 fill_between
的数据属于 string
类型造成的。如果您 print
y
、y1
和 y2
变量就在绘图之前,您可以看到问题:
>>> print(y)
['18339.1', '18280.33', '18220.61', '18160.77', '18100.92', '18042.18', '17983.51', '17577.67', '17517.87', '15956.97', '15403.36', '15344.04', '20731.34', '22986.67', '22926.7', '22867.46', '22541.08', '22481.86', '22420.94', '22361.48', '22301.09', '21972.47', '21913.41', '21251.91', '21192.85', '21133.16', '21074.7', '21014.04', '24122.28', '24063.07']
>>> print(y1)
['18734.15', '18675.39', '18614.84', '18552.15', '18493.55', '18431.77', '18371.31', '17959.34', '17898.33', '16309.96', '15746.7', '15684.44', '21171.47', '23469.15', '23408.98', '23348.73', '23015.78', '22955.47', '22895.56', '22832.68', '22771.64', '22435.43', '22376.04', '21701.94', '21642.57', '21582', '21521.39', '21461.03', '24627.21', '24566.59']
>>> print(y2)
['17944.05', '17885.26', '17826.39', '17769.39', '17708.28', '17652.59', '17595.71', '17196', '17137.42', '15603.98', '15060.03', '15003.65', '20291.2', '22504.18', '22444.42', '22386.19', '22066.39', '22008.25', '21946.32', '21890.28', '21830.53', '21509.52', '21450.77', '20801.88', '20743.12', '20684.31', '20628.01', '20567.05', '23617.35', '23559.55']
解决方案是在绘图之前将它们转换为数字类型(例如float
)。最简单的地方是您构建列表的地方:
Median.append( float(row[1]) )
Upper.append( float(row[2]) )
Lower.append( float(row[3]) )
现在 fill_between
将按预期工作,您的脚本将产生以下情节: