Trying to get a result similar to the below link (but only one row of bars):
Matplotlib: How to use timestamps with broken_barh?
Instead of hard coding the bar width (as per example), im trying to segment based on time .
2023-01-18 06:00:00
2023-01-19 00:00:00
2023-01-18 07:00:00
2023-01-19 03:00:00
2023-01-18 08:00:00
2023-01-19 01:00:00
2023-01-18 09:00:00
2023-01-19 05:00:00
2023-01-18 13:00:00
2023-01-19 06:00:00
2023-01-18 14:00:00
2023-01-18 19:00:00
2023-01-18 18:00:00
2023-01-18 18:00:00
When printing 'i', end has the same number:
([(465006, 465028)], 22)
([(465008, 465026)], 20)
([(465009, 465025)], 23)
([(465010, 465010)], 19)
([(465011, 465029)], 18)
([(465012, 465022)], 21)
([(465013, 465030)], 24)
Not sure what's going on, any assistant appreciated.
Code:
import numpy as np
import matplotlib.pylab as plt
import pandas as pd
def make_broken_barhs(df):
barh = []
id_loc = []
for loc in df['ID Location'].unique().tolist():
date_idx = df.index[df['ID Location'] == loc].tolist()
print(date_idx[0] )
print()
print(date_idx[-1])
st = date_idx[0].to_period('h').ordinal
ed = date_idx[-1].to_period('h').ordinal
bar = [(st, ed)]
barh.append(bar)
id_loc.append(loc)
return barh, id_loc
def plot_df(df):
i, j = make_broken_barhs(df)
ax = df.plot()
for i in zip(i, j):
ax.broken_barh(i[0], [19, .2], facecolor='red', linewidth=i[1])
plt.show()
idx = pd.date_range('2023-01-18 06:00:00', '2023-01-19 06:00:00', freq='h')
df = pd.DataFrame({'ID Location': np.random.randint(low=18, high=25, size=(len(idx),))},
index=idx)
plot_df(df)
EDIT: Assigned incorrect variable to ed = date_idx[-1].to_period('h').ordinal, however, still shows a continuous bar, not segmented.
CodePudding user response:
Thei[0]
segments in the broken_barth
ax.broken_barh(i[0], [19, .2], facecolor='red', linewidth=i[1])
are in the wrong format.
This is because i[0]
is composed of [startplace,endplace]
.
Instead i[0]
should be build like this: [startplace,length_of_bar]
where length_of_bar=endplace-startplace
try the code bellow. i additionally gave each ax.broken_barh
a different y value to visualize it more clearly.
import numpy as np
import matplotlib.pylab as plt
import pandas as pd
def make_broken_barhs(df):
barh = []
id_loc = []
for loc in df['ID Location'].unique().tolist():
date_idx = df.index[df['ID Location'] == loc].tolist()
print(date_idx[0])
print()
print(date_idx[-1])
st = date_idx[0].to_period('h').ordinal
ed = date_idx[-1].to_period('h').ordinal
len_bar=ed-st
bar = [(st, len_bar)]
barh.append(bar)
id_loc.append(loc)
return barh, id_loc
def plot_df(df):
i, j = make_broken_barhs(df)
print(i,j)
ax = df.plot()
z=19
for item in i:
z =1
ax.broken_barh(item, [z, 0.2], facecolor='red', linewidth=j[1])
plt.show()
idx = pd.date_range('2023-01-18 06:00:00', '2023-01-19 06:00:00', freq='h')
df = pd.DataFrame({'ID Location': np.random.randint(low=18, high=25, size=(len(idx),))},
index=idx)
plot_df(df)