Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filling in the space between lines with matplotlib

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.

enter image description here

#!/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
like image 692
Jon Avatar asked Dec 05 '25 14:12

Jon


1 Answers

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: Working output plot, using float values

like image 64
mfitzp Avatar answered Dec 07 '25 17:12

mfitzp