首页 > 解决方案 > 当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()

标签: pythonpandasmatplotlib

解决方案


在最新的 pandas 和 matplotlib 版本中,使用日期有了很大的发展。因此,引用旧帖子可能会产生误导。以下代码已使用 matplotlib 3.4.1 和 pandas 1.2.4 进行了测试。

问题代码中的一些奇怪之处在于,首先使用x0and x1,然后使用x1x2没有给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()

与熊猫日期时间填充_之间


推荐阅读