python - 在 Matplotlib 散点图中突出显示数据间隙 (NaN)
问题描述
我正在 matplotlib 中绘制一些来自 pandas 的基于时间的数据(可能是数万行),我想突出显示数据中存在 NaN 的时段。我认为实现这一点的方法是使用 axvspan 在有数据间隙的地方开始和停止绘图上绘制一个红色框。我确实考虑过每次使用 axvline 有一个 NaN 时只画一条垂直线,但这可能会在绘图上创建数千个对象并导致生成的 PNG 需要很长时间才能写入。所以我认为使用 axvspan 更合适。但是,我遇到的困难是找到 NaN 组的开始和停止索引。
下面的代码不是来自我的实际代码,它只是一个基本模型,用于显示我想要实现的目标。
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
days = pd.date_range(datetime.now(), datetime.now() + timedelta(13), freq='D')
data = [2,2.3,3,np.nan, np.nan,4.7,3.4,3.1,2.7,np.nan,np.nan,np.nan,4,4.5]
df = pd.DataFrame({'idx': days, 'col': data})
df = df.set_index('idx')
print(df)
#Code to find the start index and stop index of the groups of NaNs
# resuls in list which contains lists of each gap start and stop datetime
gaps = []
plt.plot(df.index, df['col'])
for gap in gaps:
plt.axvspan(gap[0], gap[1], facecolor='r', alpha=0.5)
plt.show()
其他可视化间隙的建议也将不胜感激。比如一条不同颜色的直线使用某种填充连接跨越间隙的数据?
解决方案
col
要查找 NaN 组的开始和停止索引,您可以首先创建一个变量来保存is的布尔值NaN
。valid
使用此变量,您可以找到在和NaN
值之间存在转换的行。这可以使用shift
(在数据帧上移动一行) 和来完成ne
,这样您可以比较两个连续的行并确定值在哪里交替。之后,申请cumsum
创建不同的连续数据组valid
和NaN
值。
现在,仅使用具有NaN
值 ( df[is_nan]
) 的行使用groupby
withn_groups
来收集同一组内的间隙。接下来,应用aggregate
返回单个元组,其中包含每个组的开始和结束时间戳。这里的用途DateOffset
是将矩形显示扩展到所需图像输出之后的相邻点。您现在可以使用['col'].values
访问返回的数据框aggregate
并将其转换为列表。
...
...
df = df.set_index('idx')
print(df)
# Code to find the start index and stop index of the groups of NaNs
is_nan = df['col'].isna()
n_groups = is_nan.ne(is_nan.shift()).cumsum()
gap_list = df[is_nan].groupby(n_groups).aggregate(
lambda x: (
x.index[0] + pd.DateOffset(days=-1),
x.index[-1] + pd.DateOffset(days=+1)
)
)["col"].values
# resuls in list which contains tuples of each gap start and stop datetime
gaps = gap_list
plt.plot(df.index, df['col'], marker='o' )
plt.xticks(df.index, rotation=45)
for gap in gaps:
plt.axvspan(gap[0], gap[1], facecolor='r', alpha=0.5)
plt.grid()
plt.show()
推荐阅读
- android - 将自定义标签添加到材料范围滑块
- javascript - 获取表格单元格的选择选项值
- javascript - 单击其他视频时无法删除暂停/播放按钮
- javascript - 背景图片不合适
- c++ - opengl点光源phong镜面反射问题
- sql-server - 如何为我的 first_name 列设置不等式 SARGable?
- javascript - 我对“if”指令的正确构造有疑问
- java - 我想使用 volley android studio 使用 multipart 将多个图像上传到服务器
- python - 如何从python中的xml获取第4个子项
- node.js - 如何使用 docker 在 Node.js 中创建 HTTPS 服务器?