pythonpython-2.7python-iris

plt.fill_between not working in python


I am using the following code in python (iris, numpy and matplotlib) (where CCCma, CRU and UDel are all cubes predefined):

#We want to plot the mean for the whole region so we need a mean of all the lats and lons
CCCma_mean = CCCma.collapsed(['latitude', 'longitude'], iris.analysis.MEAN, weights=CCCma_grid_areas)
CRU_mean = CRU.collapsed(['latitude', 'longitude'], iris.analysis.MEAN, weights=CRU_grid_areas)                                              
UDel_mean = UDel.collapsed(['latitude', 'longitude'], iris.analysis.MEAN, weights=UDel_grid_areas)                                                 


#PART 4: PLOT LINE GRAPH  
#limit x axis    
plt.xlim((1990,2008))    

#assign the line colours
qplt.plot(CCCma_mean.coord('year'), CCCma_mean, label='CanRCM4_ERAINT', lw=1.5, color='blue')
qplt.plot(CRU_mean.coord('year'), CRU_mean, label='Observed_CRU', lw=2, color='black')
qplt.plot(UDel_mean.coord('year'), UDel_mean, label='Observed_UDel', lw=2, color='black', linestyle='--')

#create a legend and set its location to under the graph
plt.legend(loc="upper center", bbox_to_anchor=(0.5,-0.05), fancybox=True, shadow=True, ncol=2)

#create a title
plt.title('Mean Near Surface Temperature for Malawi 1989-2008', fontsize=11)   

#add grid lines
plt.grid()

#save the image of the graph and include full legend
#plt.savefig('ERAINT_Temperature_LineGraph_Annual', bbox_inches='tight')

#show the graph in the console
iplt.show()

This creates this nice graph enter image description here

What I would like to do is fill in the area (shade) between the two observed datasets. I have tried to add this code:

#fill error area for observed data
x = np.arange(1990,2008,1)    
plt.fill_between(x, CRU_mean, UDel_mean, color='grey', alpha='0.5')

But when I do, no fill is added, the legend disappears and this error comes up:

  File "/exports/csce/datastore/geos/users/s0XXXX/Climate_Modelling/Python_Code_and_Output_Images/Templates/Line_Graph_Tas_Template_Annual_Only.py", line 116, in main
    plt.fill_between(x, CRU_mean, UDel_mean, color='grey', alpha='0.5')

  File "/scratch/s0XXXX/anaconda/lib/python2.7/site-packages/matplotlib/pyplot.py", line 2896, in fill_between
    **kwargs)

  File "/scratch/s0XXXX/anaconda/lib/python2.7/site-packages/matplotlib/__init__.py", line 1819, in inner
    return func(ax, *args, **kwargs)

  File "/scratch/s0XXXX/anaconda/lib/python2.7/site-packages/matplotlib/axes/_axes.py", line 4582, in fill_between
    y1 = ma.masked_invalid(self.convert_yunits(y1))

  File "/scratch/s0XXXX/anaconda/lib/python2.7/site-packages/numpy/ma/core.py", line 2388, in masked_invalid
    condition = ~(np.isfinite(a))

TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Any ideas how to fix this?


Solution

  • The problem is that you're passing Iris Cubes into a matlpotlib function. You need to pass the Cubes' data arrays in instead.