Matplotlib fill_between not working with plot_date, any alternatives?

I want to create a plot like this: This has integer x values

The code:

P.fill_between(DF.start.index, DF.lwr, DF.upr, facecolor='blue', alpha=.2) P.plot(DF.start.index, DF.Rt, '.') 

but with dates on the x axis like this (without ranges): with plot_date

the code:

 P.plot_date(DF.start, DF.Rt, '.') 

the problem is that fill_between fails when x values ​​are date_time objects.

Does anyone know of a workaround? DF is a pandas DataFrame.

+9
python matplotlib pandas
source share
3 answers

This will help if you show how df defined. What does df.info() report? This will show us the column types.

There are many ways to represent dates: like strings, ints, float, datetime.datetime, NumPy datetime64s, Pandas timestamps or Pandas DatetimeIndex. The right way to build depends on what you have.

Here is an example showing that your code works if df.index is DatetimeIndex:

 import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy import stats index = pd.date_range(start='2000-1-1', end='2015-1-1', freq='M') N = len(index) poisson = (stats.poisson.rvs(1000, size=(N,3))/100.0) poisson.sort(axis=1) df = pd.DataFrame(poisson, columns=['lwr', 'Rt', 'upr'], index=index) plt.fill_between(df.index, df.lwr, df.upr, facecolor='blue', alpha=.2) plt.plot(df.index, df.Rt, '.') plt.show() 

enter image description here


If the index has string representations of dates, then (with Matplotlib version 1.4.2) you will get a TypeError:

 import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy import stats index = pd.date_range(start='2000-1-1', end='2015-1-1', freq='M') N = len(index) poisson = (stats.poisson.rvs(1000, size=(N,3))/100.0) poisson.sort(axis=1) df = pd.DataFrame(poisson, columns=['lwr', 'Rt', 'upr']) index = [item.strftime('%Y-%m-%d') for item in index] plt.fill_between(index, df.lwr, df.upr, facecolor='blue', alpha=.2) plt.plot(index, df.Rt, '.') plt.show() 

gives

  File "/home/unutbu/.virtualenvs/dev/local/lib/python2.7/site-packages/numpy/ma/core.py", line 2237, in masked_invalid condition = ~(np.isfinite(a)) TypeError: Not implemented for this type 

In this case, the fix is ​​intended to convert strings to timestamps:

 index = pd.to_datetime(index) 
+16
source share

Regarding the error reported by chilliq:

 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'' 

This can be done if the columns of the DataFrame are of the dtype object type when using fill_between. Changing the column types of the example and then attempting to build as follows results in the error above:

 import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy import stats index = pd.date_range(start='2000-1-1', end='2015-1-1', freq='M') N = len(index) poisson = (stats.poisson.rvs(1000, size=(N,3))/100.0) poisson.sort(axis=1) df = pd.DataFrame(poisson, columns=['lwr', 'Rt', 'upr'], index=index) dfo = df.astype(object) plt.fill_between(df0.index, df0.lwr, df0.upr, facecolor='blue', alpha=.2) plt.show() 

From dfo.info () we see that the column types are an “object”:

 <class 'pandas.core.frame.DataFrame'> DatetimeIndex: 180 entries, 2000-01-31 to 2014-12-31 Freq: M Data columns (total 3 columns): lwr 180 non-null object Rt 180 non-null object upr 180 non-null object dtypes: object(3) memory usage: 5.6+ KB 

Ensuring that the DataFrame has numeric columns will solve the problem. For this, we can use pandas.to_numeric to convert as follows:

 dfn = dfo.apply(pd.to_numeric, errors='ignore') plt.fill_between(dfn.index, dfn.lwr, dfn.upr, facecolor='blue', alpha=.2) plt.show() 
+1
source share

I got a similar error when using fill_between:

 ufunc 'bitwise_and' not supported 

However, in my case, the cause of the error was pretty dumb. I passed the color parameter, but without an explicit argument name, which is why it was parameter # 4, which was called where So, just making sure that the keyword parameters solved the problem:

 ax.fill_between(xdata, highs, lows, color=color, alpha=0.2) 
0
source share

All Articles