I am writing a python program which plots data from a .csv file as a financial value versus a date with the format of month-day-year. One line represents an upper estimate of financial value, another the lower estimate and the third represents a mean estimate. I am trying to get the plot to fill in the area between the upper and lower estimates with red and overlay a black line representing the mean value. I can plot each data set as a line, but for some reason it is not letting me fill in the space between the upper and lower bounds with red. The plot below shows what the geometry looks like and I am trying to fill in the space between the red lines. When I run the code using the fill_between command I get the message "condition = ~(np.isfinite(a)). Can anyone spot where my problem is. I am adding a months worth of data points from the .csv file and the whole code to better understand the mechanics, or lack thereof.

#!/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")
Test data
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
The error is caused by the data passed to fill_between being of a string type. If you you print the y, y1 and y2 variables just before the plot you can see the problem:
>>> 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']
The solution is to convert these to a numeric type (e.g. float) before plotting. The easiest place is where you are constructing your lists:
Median.append( float(row[1]) )
Upper.append( float(row[2]) )
Lower.append( float(row[3]) )
Now fill_between will work as expected and your script will produce the following plot:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With