【问题标题】:Matplotlib's fill_between doesnt work with plot_date, any alternatives?Matplotlib fill_between 不适用于 plot_date,还有其他选择吗?
【发布时间】:2015-03-21 09:26:27
【问题描述】:

我想像这样创建一个情节:

代码:

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

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

代码:

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

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

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

【问题讨论】:

  • 在这个配方中它显示为工作:matplotlib.org/users/recipes.html#fill-between-and-alpha 但我收到以下错误:条件 = ~(np.isfinite(a)) TypeError: ufunc 'isfinite' not supported for the input types ,并且根据转换规则“安全”,输入无法安全地强制转换为任何支持的类型
  • DF.info() 的输出: Int64Index:967 个条目,0 到 966 数据列(共 9 列):SE 967 非空 int64开始 967 非空对象 结束 967 非空对象案例 967 非空 int64 Rt 961 非空 float64 Rt2 967 非空 float64 p1 967 非空 float64 lwr 967 非空 float64 upr 967 非空 float64 dtypes: float64(5)、int64(2)、object(2) 内存使用量:75.5+ KB 无
  • 使用 to_pydatetime() 将 numpy datetime64[ns] 类型转换为 python datetime.datetime 对象数组。解决方案取自here

标签: python matplotlib pandas


【解决方案1】:

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

日期可以通过多种方式表示:字符串、整数、浮点数、datetime.datetime、NumPy datetime64s、Pandas Timestamps 或 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()


如果索引有日期的字符串表示,那么(使用 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

在这种情况下,解决方法是将字符串转换为时间戳:

index = pd.to_datetime(index)

【讨论】:

  • 如果日期列由 Pandas datetime64 对象组成怎么办?我应该把它转换成别的东西吗?有没有办法在这些对象上使用 fill_between()?
  • 应该没有问题; plt.plotplt.fill_between 接受 dtype 数组 datetime64[ns] 就好了。
  • @unutbu 当我使用 datetime64 和 plt.fill_between() 时,我得到: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''。那么这个错误的原因应该是别的地方吧?
  • @chilliq:您能否准备一个展示问题的小示例,并将其发布在新问题中?谷歌搜索TypeError: ufunc 'isfinite' not supported for the input types 显示此错误可能是由于 matplotlib 的版本,或者在使用 dtype 'object' 的 NumPy 数组时出现的。并且可能还有其他原因。因此,如果没有可重现的示例,很难知道是什么导致了您的问题。
  • @unutbu Posted question
【解决方案2】:

关于chiliq报错:

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() 我们看到列类型是“对象”:

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

【讨论】:

    【解决方案3】:

    我在使用 fill_between 时遇到了类似的错误:

    ufunc 'bitwise_and' not supported
    

    但是,就我而言,错误的原因相当愚蠢。我正在传递颜色参数,但没有明确的参数名称,这导致它是 #4 参数,称为 where。因此,只需确保关键字参数具有 key 即可解决问题:

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

    【讨论】:

      【解决方案4】:

      我认为没有一个答案解决了最初的问题,他们都稍微改变了它。

      如果你想绘制 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 代码,实际上可以找到它们是如何绘制时间增量的。然后可以将其应用于代码,不再需要第一个绘图。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-22
        • 2011-04-21
        • 1970-01-01
        相关资源
        最近更新 更多