Matplotlib fill_between不能用于plot_date,任何替代方案?

时间:2015-01-22 14:34:39

标签: python matplotlib pandas

我想像这样创建一个情节: This has integer x values

代码:

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

但是在x轴上有日期,就像这样(没有条带): with plot_date

代码:

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

问题是当x值是date_time对象时,fill_between失败。

有没有人知道解决方法? DF是一个pandas DataFrame。

4 个答案:

答案 0 :(得分:16)

如果您展示如何定义df,将会有所帮助。 df.info()报告什么?这将向我们展示列的dtypes。

可以通过多种方式表示日期:字符串,整数,浮点数,datetime.datetime,NumPy datetime64s,Pandas时间戳或Pandas DatetimeIndex。绘制它的正确方法取决于你拥有的东西。

如果df.index是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


如果索引具有日期的字符串表示,那么(使用Matplotlib版本1.4.2)您将得到一个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()

产量

  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

在这种情况下,修复方法是将字符串转换为Timestamps:

index = pd.to_datetime(index)

答案 1 :(得分:1)

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

如果DataFrame列在使用fill_between时具有“object”dtype,则可以生成此项。更改示例列类型,然后尝试绘制,如下所示,会导致上述错误:

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()

从dfo.info()我们看到列类型是“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

确保DataFrame具有数字列将解决问题。为此,我们可以使用pandas.to_numeric进行转换,如下所示:

dfn = dfo.apply(pd.to_numeric, errors='ignore')

plt.fill_between(dfn.index, dfn.lwr, dfn.upr, facecolor='blue', alpha=.2)
plt.show()

答案 2 :(得分:0)

使用fill_between时出现类似错误:

ufunc 'bitwise_and' not supported

但是,在我的情况下,错误原因非常愚蠢。我正在传递颜色参数,但没有显式的参数名称,这导致它成为名为where的#4参数。因此,只需确保关键字参数具有关键性即可解决问题:

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

答案 3 :(得分:0)

我认为这些答案都没有解决最初的问题,它们都做了一些改动。

如果您想绘制 timdeltas,您可以使用此解决方法

ax = df.Rt.plot()
x = ax.get_lines()[0].get_xdata().astype(float)
ax.fill_between(x, df.lwr, df.upr, color="b", alpha=0.2)
plt.show()

这项工作有罪。一般来说,唯一需要注意的是,您始终需要使用 Pandas 绘制索引,然后从艺术家那里获取坐标。我确信通过查看 Pandas 代码,人们实际上可以找到它们如何绘制时间增量。然后可以将其应用于代码,并且不再需要第一个图。