python - 当x值为熊猫时间序列时如何为区域着色
问题描述
我有下面的折线图,其中包含两个时间序列值和两条垂直线,并且想为“FromGen”大于“ToCons”和两条垂直线外侧的区域着色。
start_date="2019-06-18"
end_date="2019-06-19"
x0='2019-06-18 9:00:00'
x1='2019-06-18 17:00:00'
x1= pd.to_datetime(x1, format="%Y-%m-%d", utc=True)
x2= pd.to_datetime(x2, format="%Y-%m-%d", utc=True)
zeit = (df['DateTime'] > start_date) & (df['DateTime'] <= end_date)
zeit = df.loc[zeit]
zeit.plot(figsize=(15,10),x="DateTime", y=["FromGen", "ToCons"])
plt.xlabel("Zeit")
plt.ylabel("Wh")
legend = plt.legend(title="comp",
loc=1, fontsize='large', fancybox=True, labels=['FromGen', 'ToCons'])
plt.axvline(x=x0, color='red')
plt.axvline(x=x1, color='red')
kde_x, kde_y = ax.lines[0].get_data()
ax.fill_between(kde_x, kde_y, where=(kde_x<x0) | (kde_x>x1) ,
interpolate=True, color='#8FF536')
plt.show()
我已经发现最后几行的代码可能会有所帮助 - 但目前我正在努力解决这个错误:
'numpy.ndarray' 和 'str' 的实例之间不支持'<'
提前谢谢了!
编辑:这就是我的代码目前的样子 - 如果我不将 df 转换为正确的 tz 一切都会完美。但是当我这样做时,绿色区域会移动。我想我在某处错过了时区转换,但找不到在哪里....
从日期时间导入日期时间从 pytz 导入时区
df= pd.read_csv("filename.csv", error_bad_lines=False, sep=";") df['DateTime'] = pd.to_datetime(df['DateTime'], format="%Y-%m-% d", UTC=真)
#df['DateTime'] = df['DateTime'].dt.tz_convert('Europe/Berlin') #没有这条线也很好用!但是当我使用它时,彩色区域似乎位于错误的时区
start_date = "2019-06-18" end_date = "2019-06-19"
x0 = '2019-06-18 9:00:00' x1 = '2019-06-18 16:00:00'
zeit = df.loc[(df['DateTime'] > start_date) & (df['DateTime'] <= end_date)]
ax = zeit.plot(figsize=(15, 10), x="DateTime", y=["FromGen", "ToCons"])
ax.set_xlabel("Zeit") ax.set_ylabel("Wh") legend = ax.legend(title="comp",
loc='upper right', fontsize='large', fancybox=True, labels=['FromGen', 'ToCons']) ax.axvline(x=x0, color='red') ax.axvline(x=x1, color='red')
x0 = datetime_obj.replace(tzinfo=timezone('UTC'))
ax.fill_between(zeit['DateTime'].values, zeit['FromGen'], zeit['ToCons'],
where=((zeit['FromGen'] > zeit['ToCons']) & ((zeit['DateTime'] <= x0) | (zeit['DateTime'] >=x1))),
interpolate=False, color='#8FF536') plt.show()
解决方案
在最新的 pandas 和 matplotlib 版本中,使用日期有了很大的发展。因此,引用旧帖子可能会产生误导。以下代码已使用 matplotlib 3.4.1 和 pandas 1.2.4 进行了测试。
问题代码中的一些奇怪之处在于,首先使用x0
and x1
,然后使用x1
并x2
没有给x2
.
plt.fill_between()
可以直接使用数值列。要使用 datatime 列,现在它对...['DateTime'].values
. 对于where
子句,要比较 datetime 列,需要将 x0 和 x1 转换为pd.to_datetime(...)
. 由于我的示例中的日期时间值没有utc
,因此在使用 时比较不起作用x0 = pd.to_datetime(..., utc=True)
。
另请注意,pandas plotting( zeit.plot(...)
) 返回一个 matplotlib ax
。
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
start_date = "2019-06-18"
end_date = "2019-06-19"
x0 = '2019-06-18 9:00:00'
x1 = '2019-06-18 17:00:00'
N = 200
df = pd.DataFrame({'DateTime': pd.date_range(start_date, freq='10min', periods=N),
'FromGen': 8 * np.exp(-(np.arange(N) - 80) ** 2 / 1000) + np.random.uniform(0, 0.4, N),
'ToCons': np.random.uniform(1, 1.5, N)})
x0 = pd.to_datetime(x0, format="%Y-%m-%d")
x1 = pd.to_datetime(x1, format="%Y-%m-%d")
zeit = df.loc[(df['DateTime'] > start_date) & (df['DateTime'] <= end_date)]
ax = zeit.plot(figsize=(15, 10), x="DateTime", y=["FromGen", "ToCons"])
ax.set_xlabel("Zeit")
ax.set_ylabel("Wh")
legend = ax.legend(title="comp",
loc='upper right', fontsize='large', fancybox=True, labels=['FromGen', 'ToCons'])
ax.axvline(x=x0, color='red')
ax.axvline(x=x1, color='red')
ax.fill_between(zeit['DateTime'].values, zeit['FromGen'], zeit['ToCons'],
where=(zeit['FromGen'] > zeit['ToCons']) & ((zeit['DateTime'] <= x0) | (zeit['DateTime'] >= x1)),
interpolate=False, color='#8FF536')
plt.show()
推荐阅读
- python-3.6 - 为什么我会看到 Python 套接字模块的 TypeError?
- php - 我可以在 Symfony 4 上使用 Doctrine (findOneBy()) 通过用户名和密码获取用户吗?
- python-3.x - 如何在soup.findAll python 3.2中获取一些类值
- php - 当 createQuery 中的 groupby 时,如何在奏鸣曲管理中修复“查询返回多行”
- c# - 如何在更改事件中从 Kendo().DropDownList() 的 DataValueField() 中获取值
- elasticsearch - 弹性:嵌套查询或查询弹性文档的文档键,其值为键、值对的数组
- python - 在两个excel表中匹配数据,并存储匹配的数据
- javascript - 我想在 div 中显示 js 的结果
- python - python3.6 asyncio future done() 从嵌套的 ThreadPoolExecutor(线程中的线程)调用时永远不会返回 True
- if-statement - Google Sheets Ifs 语句:只计算一个逻辑表达式