I use the following code to identify some interested values into a dataframe and them plot a time window before and after that value appeared. It works very well, but I would like to know if there is a less coding way/more pythonic way to accomplish this. Thanks in advance!
Before I go, I try to use only Seaborn on the plotting secction, but creating the subplots and filling then was easier, considering I don't want to share axis.
# Libraries
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib as mpl
import matplotlib.pyplot as plt
# Generate Data
rng = np.random.default_rng(12345)
df = pd.DataFrame(
index=pd.date_range(start="1/1/2019", periods=1035, freq='D'),
data={'value':rng.integers(-100, 30000, 1035)}
).reset_index()
# Creating a boolean for interesting values
df['select'] = df['value'] < 0
# Finding days with interested value and creating the periods
lt_dates = df.loc[df['select'], 'index'].to_list()
lt_days_after = [pd.DataFrame(index=pd.date_range(start=day, periods=14, freq='D')).reset_index() for day in lt_dates]
lt_days_before = [pd.DataFrame(index=pd.date_range(end=day, periods=14, freq='D')).reset_index() for day in lt_dates]
# Concatenating the periods
df_mask = pd.concat(objs=[pd.concat(lt_days_after), pd.concat(lt_days_before)]).sort_values('index').drop_duplicates(ignore_index=True)
# Flagging days
df['grouped'] = df['index'].isin(df_mask['index'])
# Creating the groups
df['slice'] = (~df['grouped']).cumsum()
groups = df.loc[df['grouped'], 'slice'].unique()
groups_dict = {y: x for x, y in enumerate(groups)}
# Filtering non interested values
df = df.loc[df['grouped']]
df['slice'].replace(groups_dict, inplace=True)
# Plotting
rows = len(groups_dict)
# Function to fill the subplots
def subplot_df(_ax, x):
sns.lineplot(
x="index",
y='value',
ci=None,
data=df[df['slice'] == x],
ax=_ax
)
_ax.set_xlabel('')
f, ax = plt.subplots(
nrows=rows,
figsize=(12, 2*rows),
sharex=False,
sharey=False
)
# Filling a single or multiple subplots
if rows != 0:
for x in range(rows):
subplot_df(ax[x], x)
else:
subplot_df(ax, 0)