Below is my working code. Find dataset here: 21.8 KB file on MEGA
import pandas as pd
from abc import ABC
from dataclasses import dataclass
import arrow
from plotly import express as px, graph_objects as go
from datetime import datetime
@dataclass
class Event(ABC):
name: str
date: arrow
description: str | None
period: str | None
@dataclass
class Interval(ABC):
name: str
start: Event
end: Event
def length(self, unit:str) -> int | str:
l = (self.end.date - self.start.date).days
match unit:
case 'seconds':
return l * 24 * 60 * 60
case 'minutes':
return l * 24 * 60
case 'hours':
return l * 24
case 'days':
return l
case 'weeks':
return l // 7
case 'months':
return (l / 365) * 12
case 'years':
return l / 365
case _:
return "I don't know this unit"
def return_datetime(date: str) -> datetime:
return datetime.strptime(date, '%Y-%m-%d')
cher = pd.read_csv('cher2.csv')
cher['date'] = cher['date'].apply(return_datetime)
events, interval_start, interval_end, intervals = [], [], [], []
for r in cher.itertuples(index=False):
if r[2] == 0:
ev = Event(name=r[0], date=r[1], description=None, period='start')
events.append(ev)
interval_start.append(ev)
elif r[2] == 1:
ev = Event(name=r[0], date=r[1], description=None, period='end')
events.append(ev)
interval_end.append(ev)
else:
ev = Event(name=r[0], date=r[1], description=None, period=None)
events.append(ev)
intervals2 = [
(interval.name, interval.start.date, interval.end.date, 0.5)
for interval in intervals
]
df = pd.DataFrame(intervals2)
df2 = pd.DataFrame(events)
df2['y'] = 3
fig = px.timeline(
data_frame=df,
x_start=1,
x_end=2,
y=3,
color=0,
color_discrete_sequence =px.colors.qualitative.Bold,
height=500,
opacity=0.6
)
fig.update_layout(showlegend=False, plot_bgcolor='white')
fig.update_yaxes(showticklabels=False, title_text=None, showgrid=False)
fig.add_trace(
go.Scatter(
x=df2['date'],
y=df2['y'],
mode='markers',
marker={'color': 'black', 'size': 3, 'symbol': '200'}
)
)
fig.update_xaxes(fixedrange=True,
showline=True,
linewidth=1,
linecolor='black',
showgrid=False,
autorange=False,
rangeslider={
'visible': True,
'yaxis': {'range': [0.2, 0.4], 'rangemode': 'fixed'},
},
rangeselector={
'visible': True,
'buttons': [
{'label': '10 years',
'step': 'year',
'stepmode': 'todate',
'count': 10},
{'label': '1 year',
'step': 'year',
'stepmode': 'backward'}
],
},
tickmode='array',
tickvals=df2['date'],
ticklen=240,
tickcolor='black',
tickwidth=1,
showspikes=True,
spikecolor='blue',
ticks='inside',
tickformat='%d %b <br>%Y'
)
fig.show()