Matplotlib 的 fill_between 不适用于 plot_date,还有其他选择吗?
Matplotlib's fill_between doesnt work with plot_date, any alternatives?
我想像这样创建一个情节:
代码:
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。
如果您显示 df
是如何定义的,将会有所帮助。 df.info()
报告了什么?这将向我们展示列的数据类型。
日期有多种表示方式:字符串、整数、浮点数、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()
如果索引有日期的字符串表示,那么(使用 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)
关于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''
如果使用 fill_between 时 DataFrame 列具有 "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()
我在使用 fill_between 时遇到了类似的错误:
ufunc 'bitwise_and' not supported
然而,在我的例子中,错误的原因是相当愚蠢的。我正在传递颜色参数,但没有明确的参数名称,这导致它成为名为 where
的 #4 参数。因此,只需确保关键字参数具有关键即可解决问题:
ax.fill_between(xdata, highs, lows, color=color, alpha=0.2)
我认为 none 的答案解决了原始问题,他们都做了一点改动。
如果你想绘制时间增量,你可以使用这个解决方法
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 代码,人们实际上可以找到他们如何绘制时间增量。然后可以将其应用于代码,不再需要第一个图。
我想像这样创建一个情节:
代码:
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。
如果您显示 df
是如何定义的,将会有所帮助。 df.info()
报告了什么?这将向我们展示列的数据类型。
日期有多种表示方式:字符串、整数、浮点数、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()
如果索引有日期的字符串表示,那么(使用 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)
关于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''
如果使用 fill_between 时 DataFrame 列具有 "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()
我在使用 fill_between 时遇到了类似的错误:
ufunc 'bitwise_and' not supported
然而,在我的例子中,错误的原因是相当愚蠢的。我正在传递颜色参数,但没有明确的参数名称,这导致它成为名为 where
的 #4 参数。因此,只需确保关键字参数具有关键即可解决问题:
ax.fill_between(xdata, highs, lows, color=color, alpha=0.2)
我认为 none 的答案解决了原始问题,他们都做了一点改动。
如果你想绘制时间增量,你可以使用这个解决方法
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 代码,人们实际上可以找到他们如何绘制时间增量。然后可以将其应用于代码,不再需要第一个图。